From db211311850ca19e8a652c1540132c69e6b65eee Mon Sep 17 00:00:00 2001 From: Harvey Tindall Date: Thu, 7 Sep 2023 14:00:30 +0100 Subject: [PATCH] accounts: allow disabling of referrals for users --- api-users.go | 25 +++++++++++++++++++++++++ lang/admin/en-us.json | 1 + router.go | 1 + ts/modules/accounts.ts | 33 ++++++++++++++++++++++++++++++++- 4 files changed, 59 insertions(+), 1 deletion(-) diff --git a/api-users.go b/api-users.go index c3d38f3..50fd259 100644 --- a/api-users.go +++ b/api-users.go @@ -634,6 +634,7 @@ func (app *appContext) ExtendExpiry(gc *gin.Context) { // @Summary Enable referrals for the given user(s) based on the rules set in the given invite code, or profile. // @Produce json +// @Param EnableDisableReferralDTO body EnableDisableReferralDTO true "List of users" // @Param mode path string true "mode of template sourcing from 'invite' or 'profile'." // @Param source path string true "invite code or profile name, depending on what mode is." // @Success 200 {object} boolResponse @@ -689,6 +690,30 @@ func (app *appContext) EnableReferralForUsers(gc *gin.Context) { } } +// @Summary Disable referrals for the given user(s). +// @Produce json +// @Param EnableDisableReferralDTO body EnableDisableReferralDTO true "List of users" +// @Success 200 {object} boolResponse +// @Router /users/referral [delete] +// @Security Bearer +// @tags Users +func (app *appContext) DisableReferralForUsers(gc *gin.Context) { + var req EnableDisableReferralDTO + gc.BindJSON(&req) + for _, u := range req.Users { + // 1. Delete directly bound template + app.storage.db.DeleteMatching(Invite{}, badgerhold.Where("ReferrerJellyfinID").Eq(u)) + // 2. Check for and delete profile-attached template + user, ok := app.storage.GetEmailsKey(u) + if !ok { + continue + } + user.ReferralTemplateKey = "" + app.storage.SetEmailsKey(u, user) + } + respondBool(200, true, gc) +} + // @Summary Send an announcement via email to a given list of users. // @Produce json // @Param announcementDTO body announcementDTO true "Announcement request object" diff --git a/lang/admin/en-us.json b/lang/admin/en-us.json index d799318..6ffa56a 100644 --- a/lang/admin/en-us.json +++ b/lang/admin/en-us.json @@ -65,6 +65,7 @@ "modifySettings": "Modify Settings", "modifySettingsDescription": "Apply settings from an existing profile, or source them directly from a user.", "enableReferrals": "Enable Referrals", + "disableReferrals": "Disable Referrals", "enableReferralsDescription": "Give users a personal referral link similiar to an invite, to send to friends/family. Can be sourced from a referral template in a profile, or from an existing invite.", "enableReferralsProfileDescription": "Give users created with this profile a personal referral link similiar to an invite, to send to friends/family. Create an invite with the desired settings, then select it here. Each referral will then be based on this invite. You can delete the invite once complete.", "applyHomescreenLayout": "Apply homescreen layout", diff --git a/router.go b/router.go index 4042c87..e2426cc 100644 --- a/router.go +++ b/router.go @@ -228,6 +228,7 @@ func (app *appContext) loadRoutes(router *gin.Engine) { api.POST(p+"/matrix/login", app.MatrixLogin) if app.config.Section("user_page").Key("referrals").MustBool(false) { api.POST(p+"/users/referral/:mode/:source", app.EnableReferralForUsers) + api.DELETE(p+"/users/referral", app.DisableReferralForUsers) api.POST(p+"/profiles/referral/:profile/:invite", app.EnableReferralForProfile) api.DELETE(p+"/profiles/referral/:profile", app.DisableReferralForProfile) } diff --git a/ts/modules/accounts.ts b/ts/modules/accounts.ts index 40f8445..cab57d6 100644 --- a/ts/modules/accounts.ts +++ b/ts/modules/accounts.ts @@ -1225,6 +1225,7 @@ export class accountsList { let anyNonExpiries = list.length == 0 ? true : false; let allNonExpiries = true; let noContactCount = 0; + let referralState = Number(this._users[list[0]].referrals_enabled); // -1 = hide, 0 = show "enable", 1 = show "disable" // Only show enable/disable button if all selected have the same state. this._shouldEnable = this._users[list[0]].disabled let showDisableEnable = true; @@ -1244,6 +1245,9 @@ export class accountsList { if (!this._users[id].lastNotifyMethod()) { noContactCount++; } + if (window.referralsEnabled && referralState != -1 && Number(this._users[id].referrals_enabled) != referralState) { + referralState = -1; + } } this._settingExpiry = false; if (!anyNonExpiries && !allNonExpiries) { @@ -1277,6 +1281,22 @@ export class accountsList { this._disableEnable.parentElement.classList.remove("unfocused"); this._disableEnable.textContent = message; } + if (window.referralsEnabled) { + if (referralState == -1) { + this._enableReferrals.classList.add("unfocused"); + } else { + this._enableReferrals.classList.remove("unfocused"); + } + if (referralState == 0) { + this._enableReferrals.classList.add("~urge"); + this._enableReferrals.classList.remove("~warning"); + this._enableReferrals.textContent = window.lang.strings("enableReferrals"); + } else if (referralState == 1) { + this._enableReferrals.classList.add("~warning"); + this._enableReferrals.classList.remove("~urge"); + this._enableReferrals.textContent = window.lang.strings("disableReferrals"); + } + } } } @@ -1708,6 +1728,17 @@ export class accountsList { const modalHeader = document.getElementById("header-enable-referrals-user"); modalHeader.textContent = window.lang.quantity("enableReferralsFor", this._collectUsers().length) let list = this._collectUsers(); + + // Check if we're disabling or enabling + if (this._users[list[0]].referrals_enabled) { + _delete("/users/referral", {"users": list}, (req: XMLHttpRequest) => { + if (req.readyState != 4 || req.status != 200) return; + window.notifications.customSuccess("disabledReferralsSuccess", window.lang.quantity("appliedSettings", list.length)); + this.reload(); + }); + return; + } + (() => { _get("/invites", null, (req: XMLHttpRequest) => { if (req.readyState != 4 || req.status != 200) return; @@ -1765,7 +1796,7 @@ export class accountsList { if (req.status == 400) { window.notifications.customError("unknownError", window.lang.notif("errorUnknown")); } else if (req.status == 200 || req.status == 204) { - window.notifications.customSuccess("enableReferralsSuccess", window.lang.quantity("appliedSettings", this._collectUsers().length)); + window.notifications.customSuccess("enableReferralsSuccess", window.lang.quantity("appliedSettings", list.length)); } this.reload(); window.modals.enableReferralsUser.close();