-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -352,27 +388,47 @@
{{ .strings.enabled }}
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
diff --git a/html/form-base.html b/html/form-base.html
index cb0bb3c..aa98d32 100644
--- a/html/form-base.html
+++ b/html/form-base.html
@@ -9,6 +9,7 @@
window.messages = JSON.parse({{ .notifications }});
window.confirmation = {{ .confirmation }};
window.userExpiryEnabled = {{ .userExpiry }};
+ window.userExpiryMonths = {{ .userExpiryMonths }};
window.userExpiryDays = {{ .userExpiryDays }};
window.userExpiryHours = {{ .userExpiryHours }};
window.userExpiryMinutes = {{ .userExpiryMinutes }};
diff --git a/lang/admin/en-us.json b/lang/admin/en-us.json
index 5d2150b..f35ae02 100644
--- a/lang/admin/en-us.json
+++ b/lang/admin/en-us.json
@@ -6,6 +6,7 @@
"invites": "Invites",
"accounts": "Accounts",
"settings": "Settings",
+ "inviteMonths": "Months",
"inviteDays": "Days",
"inviteHours": "Hours",
"inviteMinutes": "Minutes",
diff --git a/lang/admin/fr-fr.json b/lang/admin/fr-fr.json
index 9a9c4fc..dfb2005 100644
--- a/lang/admin/fr-fr.json
+++ b/lang/admin/fr-fr.json
@@ -7,6 +7,7 @@
"invites": "Invitations",
"accounts": "Comptes",
"settings": "Réglages",
+ "inviteMonths": "Mois",
"inviteDays": "Jours",
"inviteHours": "Heures",
"inviteMinutes": "Minutes",
diff --git a/models.go b/models.go
index 0309d87..724d45d 100644
--- a/models.go
+++ b/models.go
@@ -30,10 +30,12 @@ type deleteUserDTO struct {
}
type generateInviteDTO struct {
+ Months int `json:"months" example:"0"` // Number of months
Days int `json:"days" example:"1"` // Number of days
Hours int `json:"hours" example:"2"` // Number of hours
Minutes int `json:"minutes" example:"3"` // Number of minutes
UserExpiry bool `json:"user-expiry"` // Whether or not user expiry is enabled
+ UserMonths int `json:"user-months,omitempty" example:"1"` // Number of months till user expiry
UserDays int `json:"user-days,omitempty" example:"1"` // Number of days till user expiry
UserHours int `json:"user-hours,omitempty" example:"2"` // Number of hours till user expiry
UserMinutes int `json:"user-minutes,omitempty" example:"3"` // Number of minutes till user expiry
@@ -73,10 +75,12 @@ type newProfileDTO struct {
type inviteDTO struct {
Code string `json:"code" example:"sajdlj23423j23"` // Invite code
+ Months int `json:"months" example:"1"` // Number of months till expiry
Days int `json:"days" example:"1"` // Number of days till expiry
Hours int `json:"hours" example:"2"` // Number of hours till expiry
Minutes int `json:"minutes" example:"3"` // Number of minutes till expiry
UserExpiry bool `json:"user-expiry"` // Whether or not user expiry is enabled
+ UserMonths int `json:"user-months,omitempty" example:"1"` // Number of months till user expiry
UserDays int `json:"user-days,omitempty" example:"1"` // Number of days till user expiry
UserHours int `json:"user-hours,omitempty" example:"2"` // Number of hours till user expiry
UserMinutes int `json:"user-minutes,omitempty" example:"3"` // Number of minutes till user expiry
@@ -212,6 +216,7 @@ type customEmailDTO struct {
type extendExpiryDTO struct {
Users []string `json:"users"` // List of user IDs to apply to.
+ Months int `json:"months" example:"1"` // Number of months to add.
Days int `json:"days" example:"1"` // Number of days to add.
Hours int `json:"hours" example:"2"` // Number of hours to add.
Minutes int `json:"minutes" example:"3"` // Number of minutes to add.
diff --git a/storage.go b/storage.go
index d8b8280..cbe823d 100644
--- a/storage.go
+++ b/storage.go
@@ -64,6 +64,7 @@ type Invite struct {
RemainingUses int `json:"remaining-uses"`
ValidTill time.Time `json:"valid_till"`
UserExpiry bool `json:"user-duration"`
+ UserMonths int `json:"user-months,omitempty"`
UserDays int `json:"user-days,omitempty"`
UserHours int `json:"user-hours,omitempty"`
UserMinutes int `json:"user-minutes,omitempty"`
diff --git a/ts/form.ts b/ts/form.ts
index 7cd775d..7bb56c6 100644
--- a/ts/form.ts
+++ b/ts/form.ts
@@ -11,6 +11,7 @@ interface formWindow extends Window {
confirmation: boolean;
confirmationModal: Modal
userExpiryEnabled: boolean;
+ userExpiryMonths: number;
userExpiryDays: number;
userExpiryHours: number;
userExpiryMinutes: number;
@@ -43,6 +44,7 @@ if (window.userExpiryEnabled) {
const messageEl = document.getElementById("user-expiry-message") as HTMLElement;
const calculateTime = () => {
let time = new Date()
+ time.setMonth(time.getMonth() + window.userExpiryMonths);
time.setDate(time.getDate() + window.userExpiryDays);
time.setHours(time.getHours() + window.userExpiryHours);
time.setMinutes(time.getMinutes() + window.userExpiryMinutes);
diff --git a/ts/modules/accounts.ts b/ts/modules/accounts.ts
index 20a8b08..7855d7b 100644
--- a/ts/modules/accounts.ts
+++ b/ts/modules/accounts.ts
@@ -217,7 +217,7 @@ export class accountsList {
private _count = 30;
private _populateNumbers = () => {
- const fieldIDs = ["days", "hours", "minutes"];
+ const fieldIDs = ["months", "days", "hours", "minutes"];
const prefixes = ["extend-expiry-"];
for (let i = 0; i < fieldIDs.length; i++) {
for (let j = 0; j < prefixes.length; j++) {
@@ -560,7 +560,7 @@ export class accountsList {
form.onsubmit = (event: Event) => {
event.preventDefault();
let send = { "users": applyList }
- for (let field of ["days", "hours", "minutes"]) {
+ for (let field of ["months", "days", "hours", "minutes"]) {
send[field] = +(document.getElementById("extend-expiry-"+field) as HTMLSelectElement).value;
}
_post("/users/extend", send, (req: XMLHttpRequest) => {
diff --git a/ts/modules/invites.ts b/ts/modules/invites.ts
index 6bddf6f..3bd2a0d 100644
--- a/ts/modules/invites.ts
+++ b/ts/modules/invites.ts
@@ -486,13 +486,17 @@ function parseInvite(invite: { [f: string]: string | number | string[][] | boole
parsed.label = invite["label"] as string || "";
let time = "";
let userExpiryTime = "";
- const fields = ["days", "hours", "minutes"];
+ const fields = ["months", "days", "hours", "minutes"];
let prefixes = [""];
if (invite["user-expiry"] as boolean) { prefixes.push("user-"); }
for (let i = 0; i < fields.length; i++) {
for (let j = 0; j < prefixes.length; j++) {
if (invite[prefixes[j]+fields[i]]) {
- let text = `${invite[prefixes[j]+fields[i]]}${fields[i][0]} `;
+ let abbreviation = fields[i][0];
+ if (fields[i] == "months") {
+ abbreviation += fields[i][1];
+ }
+ let text = `${invite[prefixes[j]+fields[i]]}${abbreviation} `;
if (prefixes[j] == "user-") {
userExpiryTime += text;
} else {
@@ -524,9 +528,11 @@ export class createInvite {
private _profile = document.getElementById("create-profile") as HTMLSelectElement;
private _label = document.getElementById("create-label") as HTMLInputElement;
+ private _months = document.getElementById("create-months") as HTMLSelectElement;
private _days = document.getElementById("create-days") as HTMLSelectElement;
private _hours = document.getElementById("create-hours") as HTMLSelectElement;
private _minutes = document.getElementById("create-minutes") as HTMLSelectElement;
+ private _userMonths = document.getElementById("user-months") as HTMLSelectElement;
private _userDays = document.getElementById("user-days") as HTMLSelectElement;
private _userHours = document.getElementById("user-hours") as HTMLSelectElement;
private _userMinutes = document.getElementById("user-minutes") as HTMLSelectElement;
@@ -542,7 +548,7 @@ export class createInvite {
private _count: Number = 30;
private _populateNumbers = () => {
- const fieldIDs = ["days", "hours", "minutes"];
+ const fieldIDs = ["months", "days", "hours", "minutes"];
const prefixes = ["create-", "user-"];
for (let i = 0; i < fieldIDs.length; i++) {
for (let j = 0; j < prefixes.length; j++) {
@@ -597,7 +603,7 @@ export class createInvite {
set uses(n: number) { this._uses.valueAsNumber = n; }
private _checkDurationValidity = () => {
- if (this.days + this.hours + this.minutes == 0) {
+ if (this.months + this.days + this.hours + this.minutes == 0) {
this._createButton.setAttribute("disabled", "");
this._createButton.onclick = null;
} else {
@@ -606,6 +612,13 @@ export class createInvite {
}
}
+ get months(): number {
+ return +this._months.value;
+ }
+ set months(n: number) {
+ this._months.value = ""+n;
+ this._checkDurationValidity();
+ }
get days(): number {
return +this._days.value;
}
@@ -640,10 +653,17 @@ export class createInvite {
parent.classList.add("~neutral");
parent.classList.remove("~urge");
}
+ this._userMonths.disabled = !enabled;
this._userDays.disabled = !enabled;
this._userHours.disabled = !enabled;
this._userMinutes.disabled = !enabled;
}
+ get userMonths(): number {
+ return +this._userMonths.value;
+ }
+ set userMonths(n: number) {
+ this._userMonths.value = ""+n;
+ }
get userDays(): number {
return +this._userDays.value;
}
@@ -700,10 +720,12 @@ export class createInvite {
userExpiry = false;
}
let send = {
+ "months": this.months,
"days": this.days,
"hours": this.hours,
"minutes": this.minutes,
"user-expiry": userExpiry,
+ "user-months": this.userMonths,
"user-days": this.userDays,
"user-hours": this.userHours,
"user-minutes": this.userMinutes,
@@ -726,6 +748,7 @@ export class createInvite {
constructor() {
this._populateNumbers();
+ this.months = 0;
this.days = 0;
this.hours = 0;
this.minutes = 30;
@@ -734,6 +757,7 @@ export class createInvite {
this._sendToEnabled.onchange = () => { this.sendToEnabled = this.sendToEnabled; };
this.userExpiry = false;
this._userExpiryToggle.onchange = () => { this.userExpiry = this._userExpiryToggle.checked; }
+ this._userMonths.disabled = true;
this._userDays.disabled = true;
this._userHours.disabled = true;
this._userMinutes.disabled = true;
diff --git a/views.go b/views.go
index ddd2e64..0ebb212 100644
--- a/views.go
+++ b/views.go
@@ -254,6 +254,7 @@ func (app *appContext) InviteProxy(gc *gin.Context) {
"code": code,
"confirmation": app.config.Section("email_confirmation").Key("enabled").MustBool(false),
"userExpiry": inv.UserExpiry,
+ "userExpiryMonths": inv.UserMonths,
"userExpiryDays": inv.UserDays,
"userExpiryHours": inv.UserHours,
"userExpiryMinutes": inv.UserMinutes,