diff --git a/api-users.go b/api-users.go
index d735215..cb6725f 100644
--- a/api-users.go
+++ b/api-users.go
@@ -707,7 +707,7 @@ func (app *appContext) DeleteUsers(gc *gin.Context) {
respondBool(200, true, gc)
}
-// @Summary Extend time before the user(s) expiry, or create and expiry if it doesn't exist.
+// @Summary Extend time before the user(s) expiry, or create an expiry if it doesn't exist.
// @Produce json
// @Param extendExpiryDTO body extendExpiryDTO true "Extend expiry object"
// @Success 200 {object} boolResponse
@@ -737,6 +737,17 @@ func (app *appContext) ExtendExpiry(gc *gin.Context) {
respondBool(204, true, gc)
}
+// @Summary Remove an expiry from a user's account.
+// @Produce json
+// @Param id path string true "id of user to extend expiry of."
+// @Success 200 {object} boolResponse
+// @Router /users/{id}/expiry [delete]
+// @tags Users
+func (app *appContext) RemoveExpiry(gc *gin.Context) {
+ app.storage.DeleteUserExpiryKey(gc.Param("id"))
+ respondBool(200, true, gc)
+}
+
// @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"
@@ -753,6 +764,7 @@ func (app *appContext) EnableReferralForUsers(gc *gin.Context) {
var req EnableDisableReferralDTO
gc.BindJSON(&req)
mode := gc.Param("mode")
+
source := gc.Param("source")
useExpiry := gc.Param("useExpiry") == "with-expiry"
baseInv := Invite{}
diff --git a/html/admin.html b/html/admin.html
index 5a519cb..7a5a04d 100644
--- a/html/admin.html
+++ b/html/admin.html
@@ -679,7 +679,15 @@
{{ if .referralsEnabled }}
{{ .strings.enableReferrals }}
{{ end }}
- {{ .strings.extendExpiry }}
+
{{ .strings.disable }}
diff --git a/lang/admin/en-us.json b/lang/admin/en-us.json
index 75e4d1b..e52ce21 100644
--- a/lang/admin/en-us.json
+++ b/lang/admin/en-us.json
@@ -22,7 +22,6 @@
"select": "Select",
"name": "Name",
"date": "Date",
- "setExpiry": "Set expiry",
"updates": "Updates",
"update": "Update",
"download": "Download",
@@ -63,6 +62,8 @@
"keepSearchingDescription": "Only the current loaded activities were searched. Click below if you wish to search all activities.",
"contactThrough": "Contact through:",
"extendExpiry": "Extend expiry",
+ "setExpiry": "Set expiry",
+ "removeExpiry": "Remove expiry",
"sendPWRManual": "User {n} has no method of contact, press copy to get a link to send to them.",
"sendPWRSuccess": "Password reset link sent.",
"sendPWRSuccessManual": "If the user hasn't received it, press copy to get a link to manually send to them.",
diff --git a/router.go b/router.go
index e243d91..4d1fac4 100644
--- a/router.go
+++ b/router.go
@@ -173,6 +173,7 @@ func (app *appContext) loadRoutes(router *gin.Engine) {
api.GET(p+"/users", app.GetUsers)
api.POST(p+"/users", app.NewUserAdmin)
api.POST(p+"/users/extend", app.ExtendExpiry)
+ api.DELETE(p+"/users/:id/expiry", app.RemoveExpiry)
api.POST(p+"/users/enable", app.EnableDisableUsers)
api.POST(p+"/invites", app.GenerateInvite)
api.GET(p+"/invites", app.GetInvites)
diff --git a/ts/modules/accounts.ts b/ts/modules/accounts.ts
index 3f17b50..9216f8d 100644
--- a/ts/modules/accounts.ts
+++ b/ts/modules/accounts.ts
@@ -769,7 +769,9 @@ export class accountsList {
private _enableExpiry = document.getElementById("accounts-enable-expiry") as HTMLSpanElement;
private _deleteNotify = document.getElementById("delete-user-notify") as HTMLInputElement;
private _deleteReason = document.getElementById("textarea-delete-user") as HTMLTextAreaElement;
+ private _expiryDropdown = document.getElementById("accounts-expiry-dropdown") as HTMLElement;
private _extendExpiry = document.getElementById("accounts-extend-expiry") as HTMLSpanElement;
+ private _removeExpiry = document.getElementById("accounts-remove-expiry") as HTMLSpanElement;
private _enableExpiryNotify = document.getElementById("expiry-extend-enable") as HTMLInputElement;
private _enableExpiryReason = document.getElementById("textarea-extend-enable") as HTMLTextAreaElement;
private _modifySettings = document.getElementById("accounts-modify-user") as HTMLSpanElement;
@@ -985,7 +987,7 @@ export class accountsList {
if (window.emailEnabled || window.telegramEnabled) {
this._announceButton.parentElement.classList.add("unfocused");
}
- this._extendExpiry.classList.add("unfocused");
+ this._expiryDropdown.classList.add("unfocused");
this._disableEnable.parentElement.classList.add("unfocused");
this._sendPWR.classList.add("unfocused");
} else {
@@ -1021,7 +1023,7 @@ export class accountsList {
for (let id of list) {
if (!anyNonExpiries && !this._users[id].expiry) {
anyNonExpiries = true;
- this._extendExpiry.classList.add("unfocused");
+ this._expiryDropdown.classList.add("unfocused");
}
if (this._users[id].expiry) {
allNonExpiries = false;
@@ -1040,13 +1042,15 @@ export class accountsList {
}
this._settingExpiry = false;
if (!anyNonExpiries && !allNonExpiries) {
- this._extendExpiry.classList.remove("unfocused");
+ this._expiryDropdown.classList.remove("unfocused");
this._extendExpiry.textContent = window.lang.strings("extendExpiry");
+ this._removeExpiry.classList.remove("unfocused");
}
if (allNonExpiries) {
- this._extendExpiry.classList.remove("unfocused");
+ this._expiryDropdown.classList.remove("unfocused");
this._extendExpiry.textContent = window.lang.strings("setExpiry");
this._settingExpiry = true;
+ this._removeExpiry.classList.add("unfocused");
}
// Only show "Send PWR" if a maximum of 1 user selected doesn't have a contact method
if (noContactCount > 1) {
@@ -1598,6 +1602,29 @@ export class accountsList {
window.modals.enableReferralsUser.show();
}
+ removeExpiry = () => {
+ const list = this._collectUsers();
+
+ let success = true;
+ for (let id of list) {
+ _delete("/users/" + id + "/expiry", null, (req: XMLHttpRequest) => {
+ if (req.readyState != 4) return;
+ if (req.status != 200) {
+ success = false;
+ return;
+ }
+ });
+ if (!success) break;
+ }
+
+ if (success) {
+ window.notifications.customSuccess("modifySettingsSuccess", window.lang.quantity("appliedSettings", list.length));
+ } else {
+ window.notifications.customError("modifySettingsError", window.lang.notif("errorSettingsFailed"));
+ }
+ this.reload();
+ }
+
extendExpiry = (enableUser?: boolean) => {
const list = this._collectUsers();
let applyList: string[] = [];
@@ -1792,7 +1819,8 @@ export class accountsList {
this._announceButton.parentElement.classList.add("unfocused");
this._extendExpiry.onclick = () => { this.extendExpiry(); };
- this._extendExpiry.classList.add("unfocused");
+ this._removeExpiry.onclick = () => { this.removeExpiry(); };
+ this._expiryDropdown.classList.add("unfocused");
this._disableEnable.onclick = this.enableDisableUsers;
this._disableEnable.parentElement.classList.add("unfocused");