Account Created: "hrfee"
diff --git a/lang/admin/en-us.json b/lang/admin/en-us.json
index 75673a9..d81b750 100644
--- a/lang/admin/en-us.json
+++ b/lang/admin/en-us.json
@@ -134,8 +134,8 @@
"builtBy": "Built By",
"loginNotAdmin": "Not an Admin?",
"referrer": "Referrer",
- "accountLinked": "{user}: {contactMethod} linked",
- "accountUnlinked": "{user}: {contactMethod} removed",
+ "accountLinked": "{contactMethod} linked: {user}",
+ "accountUnlinked": "{contactMethod} removed: {user}",
"accountResetPassword": "{user} reset their password",
"accountChangedPassword": "{user} changed their password",
"accountCreated": "Account created: {user}",
@@ -146,7 +146,8 @@
"userDeleted": "User was deleted.",
"userDisabled": "User was disabled",
"inviteCreated": "Invite created: {invite}",
- "inviteDeleted": "Invite deleted: {invite}"
+ "inviteDeleted": "Invite deleted: {invite}",
+ "inviteExpired": "Invite expired: {invite}"
},
"notifications": {
"changedEmailAddress": "Changed email address of {n}.",
diff --git a/models.go b/models.go
index 0a4afa6..b8573fe 100644
--- a/models.go
+++ b/models.go
@@ -432,14 +432,16 @@ type EnableDisableReferralDTO struct {
}
type ActivityDTO struct {
- ID string `json:"id"`
- Type string `json:"type"`
- UserID string `json:"user_id"`
- SourceType string `json:"source_type"`
- Source string `json:"source"`
- InviteCode string `json:"invite_code"`
- Value string `json:"value"`
- Time int64 `json:"time"`
+ ID string `json:"id"`
+ Type string `json:"type"`
+ UserID string `json:"user_id"`
+ Username string `json:"username"`
+ SourceType string `json:"source_type"`
+ Source string `json:"source"`
+ SourceUsername string `json:"source_username"`
+ InviteCode string `json:"invite_code"`
+ Value string `json:"value"`
+ Time int64 `json:"time"`
}
type GetActivitiesDTO struct {
diff --git a/router.go b/router.go
index edcbfdb..db34361 100644
--- a/router.go
+++ b/router.go
@@ -232,7 +232,7 @@ func (app *appContext) loadRoutes(router *gin.Engine) {
api.DELETE(p+"/profiles/referral/:profile", app.DisableReferralForProfile)
}
- api.GET(p+"/activity", app.GetActivities)
+ api.POST(p+"/activity", app.GetActivities)
if userPageEnabled {
user.GET("/details", app.MyDetails)
diff --git a/storage.go b/storage.go
index bfee54e..a3984a4 100644
--- a/storage.go
+++ b/storage.go
@@ -52,7 +52,7 @@ type Activity struct {
UserID string // ID of target user. For account creation, this will be the newly created account
SourceType ActivitySource
Source string
- InviteCode string // Only set for ActivityCreation
+ InviteCode string // Set for ActivityCreation, create/deleteInvite
Value string // Used for ActivityContactLinked, "email/discord/telegram/matrix", and Create/DeleteInvite, where it's the label.
Time time.Time
}
diff --git a/ts/modules/activity.ts b/ts/modules/activity.ts
index 104af07..940518e 100644
--- a/ts/modules/activity.ts
+++ b/ts/modules/activity.ts
@@ -1,4 +1,4 @@
-import { _get, toDateString } from "../modules/common.js";
+import { _post, toDateString } from "../modules/common.js";
export interface activity {
id: string;
@@ -9,6 +9,8 @@ export interface activity {
invite_code: string;
value: string;
time: number;
+ username: string;
+ source_username: string;
}
var activityTypeMoods = {
@@ -37,25 +39,50 @@ export class Activity { // FIXME: Add "implements"
private _expiryTypeBadge: HTMLElement;
private _act: activity;
+ _genUserLink = (): string => {
+ return `
${this._act.username || this._act.user_id.substring(0, 5)}`;
+ }
+
+ _genSrcUserLink = (): string => {
+ return `
${this._act.source_username || this._act.source.substring(0, 5)}`;
+ }
+
+ private _renderInvText = (): string => { return `
${this.value || this.invite_code || "???"}`; }
+
+ private _genInvLink = (): string => {
+ return `
${this._renderInvText()}`;
+ }
+
get type(): string { return this._act.type; }
set type(v: string) {
this._act.type = v;
let mood = activityTypeMoods[v]; // 1 = positive, 0 = neutral, -1 = negative
+ this._card.classList.remove("~warning");
+ this._card.classList.remove("~neutral");
+ this._card.classList.remove("~urge");
- for (let i = 0; i < moodColours.length; i++) {
+ if (mood == -1) {
+ this._card.classList.add("~warning");
+ } else if (mood == 0) {
+ this._card.classList.add("~neutral");
+ } else if (mood == 1) {
+ this._card.classList.add("~urge");
+ }
+
+ /* for (let i = 0; i < moodColours.length; i++) {
if (i-1 == mood) this._card.classList.add(moodColours[i]);
else this._card.classList.remove(moodColours[i]);
- }
+ } */
if (this.type == "changePassword" || this.type == "resetPassword") {
let innerHTML = ``;
if (this.type == "changePassword") innerHTML = window.lang.strings("accountChangedPassword");
else innerHTML = window.lang.strings("accountResetPassword");
- innerHTML = innerHTML.replace("{user}", `
FIXME`);
+ innerHTML = innerHTML.replace("{user}", this._genUserLink());
this._title.innerHTML = innerHTML;
} else if (this.type == "contactLinked" || this.type == "contactUnlinked") {
- let platform = this._act.type;
+ let platform = this.value;
if (platform == "email") {
platform = window.lang.strings("emailAddress");
} else {
@@ -64,40 +91,46 @@ export class Activity { // FIXME: Add "implements"
let innerHTML = ``;
if (this.type == "contactLinked") innerHTML = window.lang.strings("accountLinked");
else innerHTML = window.lang.strings("accountUnlinked");
- innerHTML = innerHTML.replace("{user}", `
FIXME`).replace("{contactMethod}", platform);
+ innerHTML = innerHTML.replace("{user}", this._genUserLink()).replace("{contactMethod}", platform);
this._title.innerHTML = innerHTML;
} else if (this.type == "creation") {
- this._title.innerHTML = window.lang.strings("accountCreated").replace("{user}", `
FIXME`);
+ this._title.innerHTML = window.lang.strings("accountCreated").replace("{user}", this._genUserLink());
if (this.source_type == "user") {
- this._referrer.innerHTML = `
${window.lang.strings("referrer")}FIXME`;
+ this._referrer.innerHTML = `
${window.lang.strings("referrer")}${this._genSrcUserLink()}`;
} else {
this._referrer.textContent = ``;
}
} else if (this.type == "deletion") {
if (this.source_type == "daemon") {
- this._title.innerHTML = window.lang.strings("accountExpired").replace("{user}", `
FIXME`);
+ this._title.innerHTML = window.lang.strings("accountExpired").replace("{user}", this._genUserLink());
this._expiryTypeBadge.classList.add("~critical");
- this._expiryTypeBadge.classList.remove("~warning");
+ this._expiryTypeBadge.classList.remove("~info");
this._expiryTypeBadge.textContent = window.lang.strings("deleted");
} else {
- this._title.innerHTML = window.lang.strings("accountDeleted").replace("{user}", `
FIXME`);
+ this._title.innerHTML = window.lang.strings("accountDeleted").replace("{user}", this._genUserLink());
}
} else if (this.type == "enabled") {
- this._title.innerHTML = window.lang.strings("accountReEnabled").replace("{user}", `
FIXME`);
+ this._title.innerHTML = window.lang.strings("accountReEnabled").replace("{user}", this._genUserLink());
} else if (this.type == "disabled") {
if (this.source_type == "daemon") {
- this._title.innerHTML = window.lang.strings("accountExpired").replace("{user}", `
FIXME`);
- this._expiryTypeBadge.classList.add("~warning");
+ this._title.innerHTML = window.lang.strings("accountExpired").replace("{user}", this._genUserLink());
+ this._expiryTypeBadge.classList.add("~info");
this._expiryTypeBadge.classList.remove("~critical");
this._expiryTypeBadge.textContent = window.lang.strings("disabled");
} else {
- this._title.innerHTML = window.lang.strings("accountDisabled").replace("{user}", `
FIXME`);
+ this._title.innerHTML = window.lang.strings("accountDisabled").replace("{user}", this._genUserLink());
}
} else if (this.type == "createInvite") {
- this._title.innerHTML = window.lang.strings("inviteCreated").replace("{invite}", `
${this.value || this.invite_code}`);
+ this._title.innerHTML = window.lang.strings("inviteCreated").replace("{invite}", this._genInvLink());
} else if (this.type == "deleteInvite") {
+ let innerHTML = ``;
+ if (this.source_type == "daemon") {
+ innerHTML = window.lang.strings("inviteExpired");
+ } else {
+ innerHTML = window.lang.strings("inviteDeleted");
+ }
- this._title.innerHTML = window.lang.strings("inviteDeleted").replace("{invite}", this.value || this.invite_code);
+ this._title.innerHTML = innerHTML.replace("{invite}", this._renderInvText());
}
/*} else if (this.source_type == "admin") {
@@ -130,14 +163,22 @@ export class Activity { // FIXME: Add "implements"
this._act.value = v;
}
+ get source(): string { return this._act.source; }
+ set source(v: string) {
+ this._act.source = v;
+ }
+
constructor(act: activity) {
this._card = document.createElement("div");
- this._card.classList.add("card", "@low");
+ this._card.classList.add("card", "@low", "my-2");
this._card.innerHTML = `
-
-
-
+
@@ -156,6 +197,10 @@ export class Activity { // FIXME: Add "implements"
this._referrer = this._card.querySelector(".activity-referrer");
this._expiryTypeBadge = this._card.querySelector(".activity-expiry-type");
+ document.addEventListener("timefmt-change", () => {
+ this.time = this.time;
+ });
+
this.update(act);
}
@@ -164,6 +209,8 @@ export class Activity { // FIXME: Add "implements"
this._act = act;
this.source_type = act.source_type;
this.invite_code = act.invite_code;
+ this.time = act.time;
+ this.source = act.source;
this.value = act.value;
this.type = act.type;
}
@@ -179,7 +226,13 @@ export class activityList {
private _activityList: HTMLElement;
reload = () => {
- _get("/activity", null, (req: XMLHttpRequest) => {
+ let send = {
+ "type": [],
+ "limit": 30,
+ "page": 0,
+ "ascending": false
+ }
+ _post("/activity", send, (req: XMLHttpRequest) => {
if (req.readyState != 4) return;
if (req.status != 200) {
window.notifications.customError("loadActivitiesError", window.lang.notif("errorLoadActivities"));
@@ -193,7 +246,7 @@ export class activityList {
const activity = new Activity(act);
this._activityList.appendChild(activity.asElement());
}
- });
+ }, true);
}
constructor() {
diff --git a/userdaemon.go b/userdaemon.go
index 5ac7dcd..0e5aa47 100644
--- a/userdaemon.go
+++ b/userdaemon.go
@@ -61,10 +61,10 @@ func (app *appContext) checkUsers() {
return
}
mode := "disable"
- termPlural := "Disabling"
+ term := "Disabling"
if app.config.Section("user_expiry").Key("behaviour").MustString("disable_user") == "delete_user" {
mode = "delete"
- termPlural = "Deleting"
+ term = "Deleting"
}
contact := false
if messagesEnabled && app.config.Section("user_expiry").Key("send_email").MustBool(true) {
@@ -95,7 +95,7 @@ func (app *appContext) checkUsers() {
app.storage.DeleteUserExpiryKey(expiry.JellyfinID)
continue
}
- app.info.Printf("%s expired user \"%s\"", termPlural, user.Name)
+ app.info.Printf("%s expired user \"%s\"", term, user.Name)
// Record activity
activity := Activity{