mirror of
https://github.com/hrfee/jfa-go.git
synced 2024-11-09 20:00:12 +00:00
accounts: notify users of expiry adjustment
"Send notification message" in the extend expiry dialog will send a message to the user with their new expiry. For #345.
This commit is contained in:
parent
cd98e51ea9
commit
48a2058e81
@ -187,9 +187,9 @@ func (app *appContext) GetCustomMessageTemplate(gc *gin.Context) {
|
|||||||
values = app.email.deletedValues(app.storage.lang.Email[lang].Strings.get("reason"), app, false)
|
values = app.email.deletedValues(app.storage.lang.Email[lang].Strings.get("reason"), app, false)
|
||||||
case "UserExpiryAdjusted":
|
case "UserExpiryAdjusted":
|
||||||
if noContent {
|
if noContent {
|
||||||
msg, err = app.email.constructExpiryAdjusted(time.Time{}, "", app, true)
|
msg, err = app.email.constructExpiryAdjusted("", time.Time{}, "", app, true)
|
||||||
}
|
}
|
||||||
values = app.email.expiryAdjustedValues(time.Now(), app.storage.lang.Email[lang].Strings.get("reason"), app, false, true)
|
values = app.email.expiryAdjustedValues(username, time.Now(), app.storage.lang.Email[lang].Strings.get("reason"), app, false, true)
|
||||||
case "InviteEmail":
|
case "InviteEmail":
|
||||||
if noContent {
|
if noContent {
|
||||||
msg, err = app.email.constructInvite("", Invite{}, app, true)
|
msg, err = app.email.constructInvite("", Invite{}, app, true)
|
||||||
|
30
api-users.go
30
api-users.go
@ -293,24 +293,24 @@ func (app *appContext) newUser(req newUserDTO, confirmed bool, gc *gin.Context)
|
|||||||
if emailEnabled && app.config.Section("notifications").Key("enabled").MustBool(false) {
|
if emailEnabled && app.config.Section("notifications").Key("enabled").MustBool(false) {
|
||||||
for address, settings := range invite.Notify {
|
for address, settings := range invite.Notify {
|
||||||
if settings["notify-creation"] {
|
if settings["notify-creation"] {
|
||||||
go func() {
|
go func(addr string) {
|
||||||
msg, err := app.email.constructCreated(req.Code, req.Username, req.Email, invite, app, false)
|
msg, err := app.email.constructCreated(req.Code, req.Username, req.Email, invite, app, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
app.err.Printf("%s: Failed to construct user creation notification: %v", req.Code, err)
|
app.err.Printf("%s: Failed to construct user creation notification: %v", req.Code, err)
|
||||||
} else {
|
} else {
|
||||||
// Check whether notify "address" is an email address of Jellyfin ID
|
// Check whether notify "addr" is an email address of Jellyfin ID
|
||||||
if strings.Contains(address, "@") {
|
if strings.Contains(addr, "@") {
|
||||||
err = app.email.send(msg, address)
|
err = app.email.send(msg, addr)
|
||||||
} else {
|
} else {
|
||||||
err = app.sendByID(msg, address)
|
err = app.sendByID(msg, addr)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
app.err.Printf("%s: Failed to send user creation notification: %v", req.Code, err)
|
app.err.Printf("%s: Failed to send user creation notification: %v", req.Code, err)
|
||||||
} else {
|
} else {
|
||||||
app.info.Printf("Sent user creation notification to %s", address)
|
app.info.Printf("Sent user creation notification to %s", addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}(address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -739,6 +739,22 @@ func (app *appContext) ExtendExpiry(gc *gin.Context) {
|
|||||||
expiry.Expiry = base.AddDate(0, req.Months, req.Days).Add(time.Duration(((60 * req.Hours) + req.Minutes)) * time.Minute)
|
expiry.Expiry = base.AddDate(0, req.Months, req.Days).Add(time.Duration(((60 * req.Hours) + req.Minutes)) * time.Minute)
|
||||||
}
|
}
|
||||||
app.storage.SetUserExpiryKey(id, expiry)
|
app.storage.SetUserExpiryKey(id, expiry)
|
||||||
|
if messagesEnabled && req.Notify {
|
||||||
|
go func(uid string, exp time.Time) {
|
||||||
|
user, status, err := app.jf.UserByID(uid, false)
|
||||||
|
if status != 200 || err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
msg, err := app.email.constructExpiryAdjusted(user.Name, exp, req.Reason, app, false)
|
||||||
|
if err != nil {
|
||||||
|
app.err.Printf("%s: Failed to construct expiry adjustment notification: %v", uid, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := app.sendByID(msg, uid); err != nil {
|
||||||
|
app.err.Printf("%s: Failed to send expiry adjustment notification: %v", uid, err)
|
||||||
|
}
|
||||||
|
}(id, expiry.Expiry)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
respondBool(204, true, gc)
|
respondBool(204, true, gc)
|
||||||
}
|
}
|
||||||
|
10
email.go
10
email.go
@ -741,7 +741,7 @@ func (emailer *Emailer) constructEnabled(reason string, app *appContext, noSub b
|
|||||||
return email, nil
|
return email, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (emailer *Emailer) expiryAdjustedValues(expiry time.Time, reason string, app *appContext, noSub bool, custom bool) map[string]interface{} {
|
func (emailer *Emailer) expiryAdjustedValues(username string, expiry time.Time, reason string, app *appContext, noSub bool, custom bool) map[string]interface{} {
|
||||||
template := map[string]interface{}{
|
template := map[string]interface{}{
|
||||||
"yourExpiryWasAdjusted": emailer.lang.UserExpiryAdjusted.get("yourExpiryWasAdjusted"),
|
"yourExpiryWasAdjusted": emailer.lang.UserExpiryAdjusted.get("yourExpiryWasAdjusted"),
|
||||||
"ifPreviouslyDisabled": emailer.lang.UserExpiryAdjusted.get("ifPreviouslyDisabled"),
|
"ifPreviouslyDisabled": emailer.lang.UserExpiryAdjusted.get("ifPreviouslyDisabled"),
|
||||||
@ -750,6 +750,7 @@ func (emailer *Emailer) expiryAdjustedValues(expiry time.Time, reason string, ap
|
|||||||
"message": "",
|
"message": "",
|
||||||
}
|
}
|
||||||
if noSub {
|
if noSub {
|
||||||
|
template["helloUser"] = emailer.lang.Strings.get("helloUser")
|
||||||
empty := []string{"reason", "newExpiry"}
|
empty := []string{"reason", "newExpiry"}
|
||||||
for _, v := range empty {
|
for _, v := range empty {
|
||||||
template[v] = "{" + v + "}"
|
template[v] = "{" + v + "}"
|
||||||
@ -757,6 +758,7 @@ func (emailer *Emailer) expiryAdjustedValues(expiry time.Time, reason string, ap
|
|||||||
} else {
|
} else {
|
||||||
template["reason"] = reason
|
template["reason"] = reason
|
||||||
template["message"] = app.config.Section("messages").Key("message").String()
|
template["message"] = app.config.Section("messages").Key("message").String()
|
||||||
|
template["helloUser"] = emailer.lang.Strings.template("helloUser", tmpl{"username": username})
|
||||||
exp := app.formatDatetime(expiry)
|
exp := app.formatDatetime(expiry)
|
||||||
if !expiry.IsZero() {
|
if !expiry.IsZero() {
|
||||||
if custom {
|
if custom {
|
||||||
@ -771,7 +773,7 @@ func (emailer *Emailer) expiryAdjustedValues(expiry time.Time, reason string, ap
|
|||||||
return template
|
return template
|
||||||
}
|
}
|
||||||
|
|
||||||
func (emailer *Emailer) constructExpiryAdjusted(expiry time.Time, reason string, app *appContext, noSub bool) (*Message, error) {
|
func (emailer *Emailer) constructExpiryAdjusted(username string, expiry time.Time, reason string, app *appContext, noSub bool) (*Message, error) {
|
||||||
email := &Message{
|
email := &Message{
|
||||||
Subject: app.config.Section("user_expiry").Key("adjustment_subject").MustString(emailer.lang.UserExpiryAdjusted.get("title")),
|
Subject: app.config.Section("user_expiry").Key("adjustment_subject").MustString(emailer.lang.UserExpiryAdjusted.get("title")),
|
||||||
}
|
}
|
||||||
@ -779,9 +781,9 @@ func (emailer *Emailer) constructExpiryAdjusted(expiry time.Time, reason string,
|
|||||||
var template map[string]interface{}
|
var template map[string]interface{}
|
||||||
message := app.storage.MustGetCustomContentKey("UserExpiryAdjusted")
|
message := app.storage.MustGetCustomContentKey("UserExpiryAdjusted")
|
||||||
if message.Enabled {
|
if message.Enabled {
|
||||||
template = emailer.expiryAdjustedValues(expiry, reason, app, noSub, true)
|
template = emailer.expiryAdjustedValues(username, expiry, reason, app, noSub, true)
|
||||||
} else {
|
} else {
|
||||||
template = emailer.expiryAdjustedValues(expiry, reason, app, noSub, false)
|
template = emailer.expiryAdjustedValues(username, expiry, reason, app, noSub, false)
|
||||||
}
|
}
|
||||||
if noSub {
|
if noSub {
|
||||||
template["newExpiry"] = emailer.lang.UserExpiryAdjusted.template("newExpiry", tmpl{
|
template["newExpiry"] = emailer.lang.UserExpiryAdjusted.template("newExpiry", tmpl{
|
||||||
|
@ -60,6 +60,8 @@
|
|||||||
<mj-section mj-class="bg">
|
<mj-section mj-class="bg">
|
||||||
<mj-column>
|
<mj-column>
|
||||||
<mj-text mj-class="text" font-size="16px" font-family="Noto Sans, Helvetica, Arial, sans-serif">
|
<mj-text mj-class="text" font-size="16px" font-family="Noto Sans, Helvetica, Arial, sans-serif">
|
||||||
|
<p>{{ .helloUser }}</p>
|
||||||
|
|
||||||
<h3>{{ .yourExpiryWasAdjusted }}</h3>
|
<h3>{{ .yourExpiryWasAdjusted }}</h3>
|
||||||
|
|
||||||
<p>{{ .ifPreviouslyDisabled }}</p>
|
<p>{{ .ifPreviouslyDisabled }}</p>
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
{{ .helloUser }}
|
||||||
|
|
||||||
{{ .yourExpiryWasAdjusted }}
|
{{ .yourExpiryWasAdjusted }}
|
||||||
|
|
||||||
{{ .ifPreviouslyDisabled }}
|
{{ .ifPreviouslyDisabled }}
|
||||||
@ -7,4 +9,3 @@
|
|||||||
{{ .reasonString }}: {{ .reason }}
|
{{ .reasonString }}: {{ .reason }}
|
||||||
|
|
||||||
{{ .message }}
|
{{ .message }}
|
||||||
|
|
||||||
|
14
models.go
14
models.go
@ -261,12 +261,14 @@ type customEmailDTO struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type extendExpiryDTO struct {
|
type extendExpiryDTO struct {
|
||||||
Users []string `json:"users"` // List of user IDs to apply to.
|
Users []string `json:"users"` // List of user IDs to apply to.
|
||||||
Months int `json:"months" example:"1"` // Number of months to add.
|
Months int `json:"months" example:"1"` // Number of months to add.
|
||||||
Days int `json:"days" example:"1"` // Number of days to add.
|
Days int `json:"days" example:"1"` // Number of days to add.
|
||||||
Hours int `json:"hours" example:"2"` // Number of hours to add.
|
Hours int `json:"hours" example:"2"` // Number of hours to add.
|
||||||
Minutes int `json:"minutes" example:"3"` // Number of minutes to add.
|
Minutes int `json:"minutes" example:"3"` // Number of minutes to add.
|
||||||
Timestamp int64 `json:"timestamp"` // Optional, exact time to expire at. Overrides other fields.
|
Timestamp int64 `json:"timestamp"` // Optional, exact time to expire at. Overrides other fields.
|
||||||
|
Notify bool `json:"notify"` // Whether to message the user(s) about the change.
|
||||||
|
Reason string `json:"reason" example:"i felt like it"` // Reason for adjustment.
|
||||||
}
|
}
|
||||||
|
|
||||||
type checkUpdateDTO struct {
|
type checkUpdateDTO struct {
|
||||||
|
@ -1684,22 +1684,25 @@ export class accountsList {
|
|||||||
applyList.push(id);
|
applyList.push(id);
|
||||||
}
|
}
|
||||||
this._enableExpiryReason.classList.add("unfocused");
|
this._enableExpiryReason.classList.add("unfocused");
|
||||||
|
this._enableExpiryNotify.parentElement.classList.remove("unfocused");
|
||||||
|
this._enableExpiryNotify.checked = false;
|
||||||
|
this._enableExpiryReason.value = "";
|
||||||
let header: string;
|
let header: string;
|
||||||
if (enableUser) {
|
if (enableUser) {
|
||||||
header = window.lang.quantity("reEnableUsers", list.length);
|
header = window.lang.quantity("reEnableUsers", list.length);
|
||||||
this._enableExpiryNotify.parentElement.classList.remove("unfocused");
|
|
||||||
this._enableExpiryNotify.checked = false;
|
|
||||||
this._enableExpiryReason.value = "";
|
|
||||||
} else if (this._settingExpiry) {
|
} else if (this._settingExpiry) {
|
||||||
header = window.lang.quantity("setExpiry", list.length);
|
header = window.lang.quantity("setExpiry", list.length);
|
||||||
this._enableExpiryNotify.parentElement.classList.add("unfocused");
|
// this._enableExpiryNotify.parentElement.classList.add("unfocused");
|
||||||
} else {
|
} else {
|
||||||
header = window.lang.quantity("extendExpiry", applyList.length);
|
header = window.lang.quantity("extendExpiry", applyList.length);
|
||||||
this._enableExpiryNotify.parentElement.classList.add("unfocused");
|
// this._enableExpiryNotify.parentElement.classList.add("unfocused");
|
||||||
}
|
}
|
||||||
document.getElementById("header-extend-expiry").textContent = header;
|
document.getElementById("header-extend-expiry").textContent = header;
|
||||||
const extend = () => {
|
const extend = () => {
|
||||||
let send = { "users": applyList, "timestamp": 0 }
|
let send = { "users": applyList, "timestamp": 0, "notify": this._enableExpiryNotify.checked }
|
||||||
|
if (this._enableExpiryNotify.checked) {
|
||||||
|
send["reason"] = this._enableExpiryReason.value;
|
||||||
|
}
|
||||||
if (this._usingExtendExpiryTextInput) {
|
if (this._usingExtendExpiryTextInput) {
|
||||||
let date = (Date as any).fromString(this._extendExpiryTextInput.value) as Date;
|
let date = (Date as any).fromString(this._extendExpiryTextInput.value) as Date;
|
||||||
send["timestamp"] = Math.floor(date.getTime() / 1000);
|
send["timestamp"] = Math.floor(date.getTime() / 1000);
|
||||||
@ -1728,7 +1731,7 @@ export class accountsList {
|
|||||||
this._extendExpiryForm.onsubmit = (event: Event) => {
|
this._extendExpiryForm.onsubmit = (event: Event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
if (enableUser) {
|
if (enableUser) {
|
||||||
this._enableDisableUsers(applyList, true, this._enableExpiryNotify.checked, this._enableExpiryNotify ? this._enableExpiryReason.value : null, (req: XMLHttpRequest) => {
|
this._enableDisableUsers(applyList, true, this._enableExpiryNotify.checked, this._enableExpiryNotify.checked ? this._enableExpiryReason.value : null, (req: XMLHttpRequest) => {
|
||||||
if (req.readyState == 4) {
|
if (req.readyState == 4) {
|
||||||
if (req.status != 200 && req.status != 204) {
|
if (req.status != 200 && req.status != 204) {
|
||||||
window.modals.extendExpiry.close();
|
window.modals.extendExpiry.close();
|
||||||
|
Loading…
Reference in New Issue
Block a user