1
0
mirror of https://github.com/hrfee/jfa-go.git synced 2024-12-22 17:10:10 +00:00

userpage: show and allow modification of contact methods

This commit is contained in:
Harvey Tindall 2023-06-17 17:26:36 +01:00
parent 3e034c85d6
commit a22f032924
Signed by: hrfee
GPG Key ID: BBC65952848FB1A2
43 changed files with 422 additions and 149 deletions

View File

@ -336,6 +336,10 @@ func (app *appContext) SetContactMethods(gc *gin.Context) {
respondBool(400, false, gc) respondBool(400, false, gc)
return return
} }
app.setContactMethods(req, gc)
}
func (app *appContext) setContactMethods(req SetContactMethodsDTO, gc *gin.Context) {
if tgUser, ok := app.storage.telegram[req.ID]; ok { if tgUser, ok := app.storage.telegram[req.ID]; ok {
change := tgUser.Contact != req.Telegram change := tgUser.Contact != req.Telegram
tgUser.Contact = req.Telegram tgUser.Contact = req.Telegram

View File

@ -19,6 +19,88 @@ func (app *appContext) MyDetails(gc *gin.Context) {
return return
} }
resp.Username = user.Name resp.Username = user.Name
resp.Admin = user.Policy.IsAdministrator
resp.Disabled = user.Policy.IsDisabled
if exp, ok := app.storage.users[user.ID]; ok {
resp.Expiry = exp.Unix()
}
app.storage.loadEmails()
app.storage.loadDiscordUsers()
app.storage.loadMatrixUsers()
app.storage.loadTelegramUsers()
if emailEnabled {
resp.Email = &MyDetailsContactMethodsDTO{}
if email, ok := app.storage.emails[user.ID]; ok {
resp.Email.Value = email.Addr
resp.Email.Enabled = email.Contact
}
}
if discordEnabled {
resp.Discord = &MyDetailsContactMethodsDTO{}
if discord, ok := app.storage.discord[user.ID]; ok {
resp.Discord.Value = RenderDiscordUsername(discord)
resp.Discord.Enabled = discord.Contact
}
}
if telegramEnabled {
resp.Telegram = &MyDetailsContactMethodsDTO{}
if telegram, ok := app.storage.telegram[user.ID]; ok {
resp.Telegram.Value = telegram.Username
resp.Telegram.Enabled = telegram.Contact
}
}
if matrixEnabled {
resp.Matrix = &MyDetailsContactMethodsDTO{}
if matrix, ok := app.storage.matrix[user.ID]; ok {
resp.Matrix.Value = matrix.UserID
resp.Matrix.Enabled = matrix.Contact
}
}
gc.JSON(200, resp) gc.JSON(200, resp)
} }
// @Summary Sets whether to notify yourself through telegram/discord/matrix/email or not.
// @Produce json
// @Param SetContactMethodsDTO body SetContactMethodsDTO true "User's Jellyfin ID and whether or not to notify then through Telegram."
// @Success 200 {object} boolResponse
// @Success 400 {object} boolResponse
// @Success 500 {object} boolResponse
// @Router /my/contact [post]
// @Security Bearer
// @tags User Page
func (app *appContext) SetMyContactMethods(gc *gin.Context) {
var req SetContactMethodsDTO
gc.BindJSON(&req)
req.ID = gc.GetString("jfId")
if req.ID == "" {
respondBool(400, false, gc)
return
}
app.setContactMethods(req, gc)
}
// @Summary Logout by deleting refresh token from cookies.
// @Produce json
// @Success 200 {object} boolResponse
// @Failure 500 {object} stringResponse
// @Router /my/logout [post]
// @Security Bearer
// @tags User Page
func (app *appContext) LogoutUser(gc *gin.Context) {
cookie, err := gc.Cookie("refresh")
if err != nil {
app.debug.Printf("Couldn't get cookies: %s", err)
respond(500, "Couldn't fetch cookies", gc)
return
}
app.invalidTokens = append(app.invalidTokens, cookie)
gc.SetCookie("refresh", "invalid", -1, "/my", gc.Request.URL.Hostname(), true, true)
respondBool(200, true, gc)
}

View File

@ -46,6 +46,14 @@
<div class="card @low dark:~d_neutral mb-4" id="card-user"> <div class="card @low dark:~d_neutral mb-4" id="card-user">
<span class="heading"></span> <span class="heading"></span>
</div> </div>
<div class="grid grid-cols-2 gap-4">
<div class="card @low dark:~d_neutral" id="card-times">
</div>
<div class="card @low dark:~d_neutral" id="card-contact">
<span class="heading">{{ .strings.contactMethods }}</span>
<div class="content"></div>
</div>
</div>
</div> </div>
<script src="{{ .urlBase }}/js/user.js" type="module"></script> <script src="{{ .urlBase }}/js/user.js" type="module"></script>
</body> </body>

View File

@ -22,11 +22,6 @@
"select": "Vælg", "select": "Vælg",
"name": "Navn", "name": "Navn",
"date": "Dato", "date": "Dato",
"enabled": "Aktiveret",
"disabled": "Deaktiveret",
"reEnable": "Genaktiver",
"disable": "Deaktiver",
"admin": "Administrator",
"updates": "Opdateringer", "updates": "Opdateringer",
"update": "Opdatering", "update": "Opdatering",
"download": "Hent", "download": "Hent",
@ -136,7 +131,6 @@
"errorCreateProfile": "Kunne ikke oprette profilen {n}", "errorCreateProfile": "Kunne ikke oprette profilen {n}",
"errorSetDefaultProfile": "Standard profilen kunne ikke indstilles.", "errorSetDefaultProfile": "Standard profilen kunne ikke indstilles.",
"errorLoadUsers": "Kunne ikke indlæse brugere.", "errorLoadUsers": "Kunne ikke indlæse brugere.",
"errorSaveSettings": "Kunne ikke gemme indstillingerne.",
"errorLoadSettings": "Indstillingerne kunne ikke indlæses.", "errorLoadSettings": "Indstillingerne kunne ikke indlæses.",
"errorSetOmbiDefaults": "Ombi standarderne kunne ikke gemmes.", "errorSetOmbiDefaults": "Ombi standarderne kunne ikke gemmes.",
"errorLoadOmbiUsers": "Kunne ikke indlæse ombi brugere.", "errorLoadOmbiUsers": "Kunne ikke indlæse ombi brugere.",

View File

@ -77,17 +77,12 @@
"search": "Suchen", "search": "Suchen",
"userExpiry": "Benutzer Ablaufdatum", "userExpiry": "Benutzer Ablaufdatum",
"inviteDuration": "Invite Dauer", "inviteDuration": "Invite Dauer",
"enabled": "Aktiviert",
"userExpiryDescription": "Eine bestimmte Zeit nach der Anmeldung wird jfa-go das Konto löschen/deaktivieren. Du kannst dieses Verhalten in den Einstellungen ändern.", "userExpiryDescription": "Eine bestimmte Zeit nach der Anmeldung wird jfa-go das Konto löschen/deaktivieren. Du kannst dieses Verhalten in den Einstellungen ändern.",
"disabled": "Deaktiviert",
"admin": "Admin",
"download": "Herunterladen", "download": "Herunterladen",
"update": "Aktualisieren", "update": "Aktualisieren",
"updates": "Aktualisierungen", "updates": "Aktualisierungen",
"expiry": "Ablaufdatum", "expiry": "Ablaufdatum",
"extendExpiry": "Ablaufdatum verlängern", "extendExpiry": "Ablaufdatum verlängern",
"reEnable": "Wieder aktivieren",
"disable": "Deaktivieren",
"donate": "Spenden", "donate": "Spenden",
"conditionals": "Bedingungen", "conditionals": "Bedingungen",
"contactThrough": "Kontakt über:", "contactThrough": "Kontakt über:",
@ -129,7 +124,6 @@
"errorCreateProfile": "Fehler beim Erstellen des Profils {n}", "errorCreateProfile": "Fehler beim Erstellen des Profils {n}",
"errorSetDefaultProfile": "Fehler beim Setzen des Standardprofils.", "errorSetDefaultProfile": "Fehler beim Setzen des Standardprofils.",
"errorLoadUsers": "Fehler beim Laden der Benutzer.", "errorLoadUsers": "Fehler beim Laden der Benutzer.",
"errorSaveSettings": "Einstellungen konnten nicht gespeichert werden.",
"errorLoadSettings": "Fehler beim Laden der Einstellungen.", "errorLoadSettings": "Fehler beim Laden der Einstellungen.",
"errorSetOmbiDefaults": "Fehler beim Speichern der Ombi-Standardeinstellungen.", "errorSetOmbiDefaults": "Fehler beim Speichern der Ombi-Standardeinstellungen.",
"errorLoadOmbiUsers": "Fehler beim Laden der Ombi-Benutzer.", "errorLoadOmbiUsers": "Fehler beim Laden der Ombi-Benutzer.",

View File

@ -75,9 +75,6 @@
"download": "Λήψη", "download": "Λήψη",
"search": "Αναζήτηση", "search": "Αναζήτηση",
"inviteDuration": "Διάρκεια Πρόσκλησης", "inviteDuration": "Διάρκεια Πρόσκλησης",
"enabled": "Ενεργοποιημένο",
"disabled": "Απενεργοποιημένο",
"admin": "Διαχειριστής",
"expiry": "Λήξη", "expiry": "Λήξη",
"userExpiry": "Λήξη Χρήστη", "userExpiry": "Λήξη Χρήστη",
"userExpiryDescription": "Μετά απο ένα καθορισμένο χρόνο μετά απο κάθε εγγραφή, το jfa-go θα διαγράφει/απενεργοποιεί τον λογαριασμό. Μπορείτε να αλλάξετε αυτή την συμπεριφορά στις ρυθμίσεις.", "userExpiryDescription": "Μετά απο ένα καθορισμένο χρόνο μετά απο κάθε εγγραφή, το jfa-go θα διαγράφει/απενεργοποιεί τον λογαριασμό. Μπορείτε να αλλάξετε αυτή την συμπεριφορά στις ρυθμίσεις.",
@ -86,8 +83,6 @@
"message": "Μήνυμα", "message": "Μήνυμα",
"extendExpiry": "Παράταση λήξης", "extendExpiry": "Παράταση λήξης",
"markdownSupported": "Το Markdown υποστυρίζεται.", "markdownSupported": "Το Markdown υποστυρίζεται.",
"reEnable": "Επανα-ενεργοποίηση",
"disable": "Απενεργοποίηση",
"inviteMonths": "Μήνες" "inviteMonths": "Μήνες"
}, },
"notifications": { "notifications": {
@ -105,7 +100,6 @@
"errorCreateProfile": "Αποτυχία δημιουργίας του προφίλ {n}", "errorCreateProfile": "Αποτυχία δημιουργίας του προφίλ {n}",
"errorSetDefaultProfile": "Αποτυχία ορισμού του προκαθορισμένου προφίλ.", "errorSetDefaultProfile": "Αποτυχία ορισμού του προκαθορισμένου προφίλ.",
"errorLoadUsers": "Αποτυχία φόρτωσης χρηστών.", "errorLoadUsers": "Αποτυχία φόρτωσης χρηστών.",
"errorSaveSettings": "Αποτυχία αποθήκευσης ρυθμίσεων.",
"errorLoadSettings": "Αποτυχία φόρτωσης ρυθμίσεων.", "errorLoadSettings": "Αποτυχία φόρτωσης ρυθμίσεων.",
"errorSetOmbiDefaults": "Αποτυχία αποθήκευσης προκαθορισμένων ρυθμίσεων για το Ombi.", "errorSetOmbiDefaults": "Αποτυχία αποθήκευσης προκαθορισμένων ρυθμίσεων για το Ombi.",
"errorLoadOmbiUsers": "Αποτυχία φόρτωσης χρηστών Ombi.", "errorLoadOmbiUsers": "Αποτυχία φόρτωσης χρηστών Ombi.",

View File

@ -94,16 +94,12 @@
"contactThrough": "Contact through:", "contactThrough": "Contact through:",
"select": "Select", "select": "Select",
"date": "Date", "date": "Date",
"enabled": "Enabled",
"disabled": "Disabled",
"disable": "Disable",
"edit": "Edit", "edit": "Edit",
"extendExpiry": "Extend expiry", "extendExpiry": "Extend expiry",
"sendPWR": "Send Password Reset", "sendPWR": "Send Password Reset",
"inviteMonths": "Months", "inviteMonths": "Months",
"inviteDuration": "Invite Duration", "inviteDuration": "Invite Duration",
"add": "Add", "add": "Add",
"reEnable": "Re-enable",
"update": "Update", "update": "Update",
"user": "User", "user": "User",
"userExpiryDescription": "A specified amount of time after each signup, jfa-go will delete/disable the account. You can change this behaviour in settings.", "userExpiryDescription": "A specified amount of time after each signup, jfa-go will delete/disable the account. You can change this behaviour in settings.",
@ -148,7 +144,6 @@
"settingsApplyRestartLater": "Apply, restart later", "settingsApplyRestartLater": "Apply, restart later",
"subject": "Subject", "subject": "Subject",
"setExpiry": "Set expiry", "setExpiry": "Set expiry",
"admin": "Admin",
"download": "Download", "download": "Download",
"search": "Search", "search": "Search",
"advancedSettings": "Advanced Settings", "advancedSettings": "Advanced Settings",
@ -187,7 +182,6 @@
"errorLoadProfiles": "Failed to load profiles.", "errorLoadProfiles": "Failed to load profiles.",
"errorCreateProfile": "Failed to create profile {n}", "errorCreateProfile": "Failed to create profile {n}",
"errorLoadUsers": "Failed to load users.", "errorLoadUsers": "Failed to load users.",
"errorSaveSettings": "Couldn't save settings.",
"errorSetOmbiProfile": "Failed to store ombi profile.", "errorSetOmbiProfile": "Failed to store ombi profile.",
"errorLoadOmbiUsers": "Failed to load ombi users.", "errorLoadOmbiUsers": "Failed to load ombi users.",
"errorFailureCheckLogs": "Failed (check console/logs)", "errorFailureCheckLogs": "Failed (check console/logs)",

View File

@ -22,12 +22,7 @@
"select": "Select", "select": "Select",
"name": "Name", "name": "Name",
"date": "Date", "date": "Date",
"enabled": "Enabled",
"disabled": "Disabled",
"reEnable": "Re-enable",
"setExpiry": "Set expiry", "setExpiry": "Set expiry",
"disable": "Disable",
"admin": "Admin",
"updates": "Updates", "updates": "Updates",
"update": "Update", "update": "Update",
"download": "Download", "download": "Download",
@ -147,7 +142,6 @@
"errorCreateProfile": "Failed to create profile {n}", "errorCreateProfile": "Failed to create profile {n}",
"errorSetDefaultProfile": "Failed to set default profile.", "errorSetDefaultProfile": "Failed to set default profile.",
"errorLoadUsers": "Failed to load users.", "errorLoadUsers": "Failed to load users.",
"errorSaveSettings": "Couldn't save settings.",
"errorLoadSettings": "Failed to load settings.", "errorLoadSettings": "Failed to load settings.",
"errorSetOmbiProfile": "Failed to store ombi profile.", "errorSetOmbiProfile": "Failed to store ombi profile.",
"errorLoadOmbiUsers": "Failed to load ombi users.", "errorLoadOmbiUsers": "Failed to load ombi users.",

View File

@ -20,11 +20,6 @@
"delete": "Eliminar", "delete": "Eliminar",
"name": "Nombre", "name": "Nombre",
"date": "Fecha", "date": "Fecha",
"enabled": "Activado",
"disabled": "Desactivado",
"reEnable": "Reactivar",
"disable": "Desactivar",
"admin": "Administrador",
"updates": "Actualizaciones", "updates": "Actualizaciones",
"update": "Actualizar", "update": "Actualizar",
"download": "Descargar", "download": "Descargar",
@ -133,7 +128,6 @@
"errorCreateProfile": "No se pudo crear el perfil {n}", "errorCreateProfile": "No se pudo crear el perfil {n}",
"errorSetDefaultProfile": "No se pudo establecer el perfil predeterminado.", "errorSetDefaultProfile": "No se pudo establecer el perfil predeterminado.",
"errorLoadUsers": "No se pudieron cargar los usuarios.", "errorLoadUsers": "No se pudieron cargar los usuarios.",
"errorSaveSettings": "No se pudo guardar la configuración.",
"errorLoadSettings": "No se pudo cargar la configuración.", "errorLoadSettings": "No se pudo cargar la configuración.",
"errorSetOmbiDefaults": "No se pudieron almacenar los valores predeterminados de ombi.", "errorSetOmbiDefaults": "No se pudieron almacenar los valores predeterminados de ombi.",
"errorLoadOmbiUsers": "No se pudieron cargar los usuarios de Ombi.", "errorLoadOmbiUsers": "No se pudieron cargar los usuarios de Ombi.",

View File

@ -76,11 +76,6 @@
"edit": "Éditer", "edit": "Éditer",
"customizeMessages": "Personnaliser les e-mails", "customizeMessages": "Personnaliser les e-mails",
"inviteDuration": "Durée de l'invitation", "inviteDuration": "Durée de l'invitation",
"enabled": "Activé",
"disabled": "Désactivé",
"reEnable": "Ré-activé",
"disable": "Désactivé",
"admin": "Administrateur",
"expiry": "Expiration", "expiry": "Expiration",
"advancedSettings": "Paramètres avancés", "advancedSettings": "Paramètres avancés",
"userExpiry": "Expiration de l'utilisateur", "userExpiry": "Expiration de l'utilisateur",
@ -130,7 +125,6 @@
"errorCreateProfile": "Échec de la création du profil {n}", "errorCreateProfile": "Échec de la création du profil {n}",
"errorSetDefaultProfile": "Échec de la définition du profil par défaut.", "errorSetDefaultProfile": "Échec de la définition du profil par défaut.",
"errorLoadUsers": "Échec du chargement des utilisateurs.", "errorLoadUsers": "Échec du chargement des utilisateurs.",
"errorSaveSettings": "Impossible d'enregistrer les paramètres.",
"errorLoadSettings": "Échec du chargement des paramètres.", "errorLoadSettings": "Échec du chargement des paramètres.",
"errorSetOmbiDefaults": "Impossible de stocker les valeurs par défaut d'Ombi.", "errorSetOmbiDefaults": "Impossible de stocker les valeurs par défaut d'Ombi.",
"errorLoadOmbiUsers": "Échec du chargement des utilisateurs Ombi.", "errorLoadOmbiUsers": "Échec du chargement des utilisateurs Ombi.",

View File

@ -22,12 +22,7 @@
"select": "Kiválasztás", "select": "Kiválasztás",
"name": "Név", "name": "Név",
"date": "Dátum", "date": "Dátum",
"enabled": "Engedélyezve",
"disabled": "Tiltva",
"reEnable": "Újra engedélyezés",
"setExpiry": "Lejárat beállítása", "setExpiry": "Lejárat beállítása",
"disable": "Letiltás",
"admin": "Adminisztrátor",
"updates": "Frissítések", "updates": "Frissítések",
"update": "Frissítés", "update": "Frissítés",
"download": "Letöltés", "download": "Letöltés",
@ -134,7 +129,6 @@
"errorCreateProfile": "", "errorCreateProfile": "",
"errorSetDefaultProfile": "", "errorSetDefaultProfile": "",
"errorLoadUsers": "", "errorLoadUsers": "",
"errorSaveSettings": "",
"errorLoadSettings": "", "errorLoadSettings": "",
"errorSetOmbiProfile": "", "errorSetOmbiProfile": "",
"errorLoadOmbiUsers": "", "errorLoadOmbiUsers": "",

View File

@ -89,7 +89,6 @@
"errorCreateProfile": "Gagal membuat profil {n}", "errorCreateProfile": "Gagal membuat profil {n}",
"errorSetDefaultProfile": "Gagal menyetel profil default.", "errorSetDefaultProfile": "Gagal menyetel profil default.",
"errorLoadUsers": "Gagal memuat pengguna.", "errorLoadUsers": "Gagal memuat pengguna.",
"errorSaveSettings": "Tidak dapat menyimpan pengaturan.",
"errorLoadSettings": "Gagal memuat pengaturan.", "errorLoadSettings": "Gagal memuat pengaturan.",
"errorSetOmbiDefaults": "Gagal menyimpan default ombi.", "errorSetOmbiDefaults": "Gagal menyimpan default ombi.",
"errorLoadOmbiUsers": "Gagal memuat pengguna ombi.", "errorLoadOmbiUsers": "Gagal memuat pengguna ombi.",

View File

@ -75,9 +75,6 @@
"customizeMessages": "E-mails aanpassen", "customizeMessages": "E-mails aanpassen",
"inviteDuration": "Geldigheidsduur uitnodiging", "inviteDuration": "Geldigheidsduur uitnodiging",
"userExpiryDescription": "Een bepaalde tijd na elke aanmelding, wordt de account verwijderd/uitgeschakeld door jfa-go. Dit kan aangepast worden in de instellingen.", "userExpiryDescription": "Een bepaalde tijd na elke aanmelding, wordt de account verwijderd/uitgeschakeld door jfa-go. Dit kan aangepast worden in de instellingen.",
"enabled": "Ingeschakeld",
"disabled": "Uitgeschakeld",
"admin": "Beheerder",
"expiry": "Verloop", "expiry": "Verloop",
"userExpiry": "Gebruikersverloop", "userExpiry": "Gebruikersverloop",
"extendExpiry": "Verleng verloop", "extendExpiry": "Verleng verloop",
@ -87,8 +84,6 @@
"search": "Zoeken", "search": "Zoeken",
"advancedSettings": "Geavanceerde instellingen", "advancedSettings": "Geavanceerde instellingen",
"inviteMonths": "Maanden", "inviteMonths": "Maanden",
"reEnable": "Opnieuw inschakelen",
"disable": "Uitschakelen",
"conditionals": "Voorwaarden", "conditionals": "Voorwaarden",
"donate": "Doneer", "donate": "Doneer",
"contactThrough": "Stuur bericht via:", "contactThrough": "Stuur bericht via:",
@ -129,7 +124,6 @@
"errorCreateProfile": "Aanmaken van profile {n} mislukt", "errorCreateProfile": "Aanmaken van profile {n} mislukt",
"errorSetDefaultProfile": "Fout bij instellen van standaardprofiel.", "errorSetDefaultProfile": "Fout bij instellen van standaardprofiel.",
"errorLoadUsers": "Laden van gebruikers mislukt.", "errorLoadUsers": "Laden van gebruikers mislukt.",
"errorSaveSettings": "Opslaan van instellingen mislukt.",
"errorLoadSettings": "Laden van instellingen mislukt.", "errorLoadSettings": "Laden van instellingen mislukt.",
"errorSetOmbiDefaults": "Opslaan van ombi standaardinstellingen mislukt.", "errorSetOmbiDefaults": "Opslaan van ombi standaardinstellingen mislukt.",
"errorLoadOmbiUsers": "Laden van ombi gebruikers mislukt.", "errorLoadOmbiUsers": "Laden van ombi gebruikers mislukt.",

View File

@ -22,12 +22,7 @@
"select": "", "select": "",
"name": "Imię", "name": "Imię",
"date": "Data", "date": "Data",
"enabled": "Włączone",
"disabled": "Wyłączone",
"reEnable": "",
"setExpiry": "", "setExpiry": "",
"disable": "Wyłączone",
"admin": "Admin",
"updates": "Aktualizacje", "updates": "Aktualizacje",
"update": "Aktualizacja", "update": "Aktualizacja",
"download": "Pobierz", "download": "Pobierz",
@ -136,7 +131,6 @@
"errorCreateProfile": "", "errorCreateProfile": "",
"errorSetDefaultProfile": "", "errorSetDefaultProfile": "",
"errorLoadUsers": "", "errorLoadUsers": "",
"errorSaveSettings": "",
"errorLoadSettings": "", "errorLoadSettings": "",
"errorSetOmbiProfile": "", "errorSetOmbiProfile": "",
"errorLoadOmbiUsers": "", "errorLoadOmbiUsers": "",

View File

@ -73,11 +73,8 @@
"reset": "Redefinir", "reset": "Redefinir",
"edit": "Editar", "edit": "Editar",
"customizeMessages": "Customizar Emails", "customizeMessages": "Customizar Emails",
"disabled": "Desativado",
"userExpiryDescription": "Após um determinado período de tempo de cada inscrição, o jfa-go apagará/desabilitará a conta. Você pode alterar essa opção nas configurações.", "userExpiryDescription": "Após um determinado período de tempo de cada inscrição, o jfa-go apagará/desabilitará a conta. Você pode alterar essa opção nas configurações.",
"inviteDuration": "Duração do Convite", "inviteDuration": "Duração do Convite",
"enabled": "Habilitado",
"admin": "Admin",
"expiry": "Expira", "expiry": "Expira",
"userExpiry": "Vencimento do Usuário", "userExpiry": "Vencimento do Usuário",
"extendExpiry": "Extender o vencimento", "extendExpiry": "Extender o vencimento",
@ -87,8 +84,6 @@
"search": "Procurar", "search": "Procurar",
"advancedSettings": "Configurações Avançada", "advancedSettings": "Configurações Avançada",
"inviteMonths": "Meses", "inviteMonths": "Meses",
"reEnable": "Reativar",
"disable": "Desativar",
"conditionals": "Condicionais", "conditionals": "Condicionais",
"donate": "Doar", "donate": "Doar",
"contactThrough": "Contato através:", "contactThrough": "Contato através:",
@ -129,7 +124,6 @@
"errorCreateProfile": "Falha ao criar perfil {n}", "errorCreateProfile": "Falha ao criar perfil {n}",
"errorSetDefaultProfile": "Falha ao definir o perfil padrão.", "errorSetDefaultProfile": "Falha ao definir o perfil padrão.",
"errorLoadUsers": "Falha ao carregar usuários.", "errorLoadUsers": "Falha ao carregar usuários.",
"errorSaveSettings": "Não foi possível salvar as configurações.",
"errorLoadSettings": "Falha ao carregar as configurações.", "errorLoadSettings": "Falha ao carregar as configurações.",
"errorSetOmbiDefaults": "Falha em armazenar os padrões ombi.", "errorSetOmbiDefaults": "Falha em armazenar os padrões ombi.",
"errorLoadOmbiUsers": "Falha ao carregar usuários ombi.", "errorLoadOmbiUsers": "Falha ao carregar usuários ombi.",

View File

@ -73,10 +73,7 @@
"notifyEvent": "Meddela den:", "notifyEvent": "Meddela den:",
"notifyInviteExpiry": "Vid utgång", "notifyInviteExpiry": "Vid utgång",
"notifyUserCreation": "Vid användarskapande", "notifyUserCreation": "Vid användarskapande",
"disabled": "Inaktiverad",
"enabled": "Aktiverad",
"inviteDuration": "Varaktighet för inbjudan", "inviteDuration": "Varaktighet för inbjudan",
"admin": "Admin",
"expiry": "Löper ut", "expiry": "Löper ut",
"userExpiry": "Användarutgång", "userExpiry": "Användarutgång",
"userExpiryDescription": "Efter en angiven tid efter varje registrering så tar jfa-go bort/inaktiverar kontot. Du kan ändra detta beteende i inställningarna.", "userExpiryDescription": "Efter en angiven tid efter varje registrering så tar jfa-go bort/inaktiverar kontot. Du kan ändra detta beteende i inställningarna.",
@ -100,7 +97,6 @@
"errorCreateProfile": "Det gick inte att skapa profilen {n}", "errorCreateProfile": "Det gick inte att skapa profilen {n}",
"errorSetDefaultProfile": "Det gick inte att ange standardprofil.", "errorSetDefaultProfile": "Det gick inte att ange standardprofil.",
"errorLoadUsers": "Det gick inte att läsa in användare.", "errorLoadUsers": "Det gick inte att läsa in användare.",
"errorSaveSettings": "Det gick inte att spara inställningarna.",
"errorLoadSettings": "Det gick inte att läsa in inställningarna.", "errorLoadSettings": "Det gick inte att läsa in inställningarna.",
"errorSetOmbiDefaults": "Det gick inte att lagra ombi-standardvärden.", "errorSetOmbiDefaults": "Det gick inte att lagra ombi-standardvärden.",
"errorLoadOmbiUsers": "Det gick inte att ladda ombi-användare.", "errorLoadOmbiUsers": "Det gick inte att ladda ombi-användare.",

View File

@ -22,12 +22,7 @@
"select": "Chọn", "select": "Chọn",
"name": "Tên", "name": "Tên",
"date": "Ngày", "date": "Ngày",
"enabled": "Mở",
"disabled": "Tắt",
"reEnable": "Mở lại",
"setExpiry": "Đặt hết hạn", "setExpiry": "Đặt hết hạn",
"disable": "Tắt",
"admin": "Admin",
"updates": "Cập nhật", "updates": "Cập nhật",
"update": "Cập nhật", "update": "Cập nhật",
"download": "Tải về", "download": "Tải về",
@ -135,7 +130,6 @@
"errorCreateProfile": "", "errorCreateProfile": "",
"errorSetDefaultProfile": "", "errorSetDefaultProfile": "",
"errorLoadUsers": "", "errorLoadUsers": "",
"errorSaveSettings": "",
"errorLoadSettings": "", "errorLoadSettings": "",
"errorSetOmbiProfile": "", "errorSetOmbiProfile": "",
"errorLoadOmbiUsers": "", "errorLoadOmbiUsers": "",

View File

@ -22,11 +22,6 @@
"select": "选择", "select": "选择",
"name": "名称", "name": "名称",
"date": "日期", "date": "日期",
"enabled": "已启用",
"disabled": "已禁用",
"reEnable": "重新启用",
"disable": "禁用",
"admin": "管理员",
"updates": "更新", "updates": "更新",
"update": "更新", "update": "更新",
"download": "下载", "download": "下载",
@ -137,7 +132,6 @@
"errorCreateProfile": "创建配置文件{n}失败", "errorCreateProfile": "创建配置文件{n}失败",
"errorSetDefaultProfile": "设置默认配置文件失败。", "errorSetDefaultProfile": "设置默认配置文件失败。",
"errorLoadUsers": "加载用户列表失败。", "errorLoadUsers": "加载用户列表失败。",
"errorSaveSettings": "无法保存设置。",
"errorLoadSettings": "加载配置列表失败。", "errorLoadSettings": "加载配置列表失败。",
"errorSetOmbiDefaults": "存储Ombi默认值失败。", "errorSetOmbiDefaults": "存储Ombi默认值失败。",
"errorLoadOmbiUsers": "加载ombi用户列表失败。", "errorLoadOmbiUsers": "加载ombi用户列表失败。",

View File

@ -22,12 +22,7 @@
"select": "選擇", "select": "選擇",
"name": "帳戶名稱", "name": "帳戶名稱",
"date": "日期", "date": "日期",
"enabled": "已啟用",
"disabled": "已禁用",
"reEnable": "重新啟用",
"setExpiry": "設置到期時間", "setExpiry": "設置到期時間",
"disable": "禁用",
"admin": "管理員",
"updates": "更新", "updates": "更新",
"update": "更新", "update": "更新",
"download": "下載", "download": "下載",
@ -136,7 +131,6 @@
"errorCreateProfile": "無法創建設置文件 {n}", "errorCreateProfile": "無法創建設置文件 {n}",
"errorSetDefaultProfile": "無法設置預設設置文件。", "errorSetDefaultProfile": "無法設置預設設置文件。",
"errorLoadUsers": "無法讀取帳戶。", "errorLoadUsers": "無法讀取帳戶。",
"errorSaveSettings": "無法儲存設置。",
"errorLoadSettings": "無法讀取設置。", "errorLoadSettings": "無法讀取設置。",
"errorSetOmbiProfile": "無法儲存 ombi 設置文件。", "errorSetOmbiProfile": "無法儲存 ombi 設置文件。",
"errorLoadOmbiUsers": "無法讀取 ombi 帳戶。", "errorLoadOmbiUsers": "無法讀取 ombi 帳戶。",

View File

@ -26,12 +26,18 @@
"refresh": "Opdater", "refresh": "Opdater",
"required": "Påkrævet", "required": "Påkrævet",
"login": "Log på", "login": "Log på",
"logout": "Log ud" "logout": "Log ud",
"admin": "Administrator",
"enabled": "Aktiveret",
"disabled": "Deaktiveret",
"reEnable": "Genaktiver",
"disable": "Deaktiver"
}, },
"notifications": { "notifications": {
"errorLoginBlank": "Brugernavnet og/eller adgangskoden blev efterladt tomme.", "errorLoginBlank": "Brugernavnet og/eller adgangskoden blev efterladt tomme.",
"errorConnection": "Kunne ikke oprette forbindelse til jfa-go.", "errorConnection": "Kunne ikke oprette forbindelse til jfa-go.",
"errorUnknown": "Ukendt fejl.", "errorUnknown": "Ukendt fejl.",
"error401Unauthorized": "Adgang nægtet. Prøv at genindlæse siden." "error401Unauthorized": "Adgang nægtet. Prøv at genindlæse siden.",
"errorSaveSettings": "Kunne ikke gemme indstillingerne."
} }
} }

View File

@ -26,12 +26,18 @@
"refresh": "Aktualisieren", "refresh": "Aktualisieren",
"required": "Erforderlich", "required": "Erforderlich",
"login": "Anmelden", "login": "Anmelden",
"logout": "Abmelden" "logout": "Abmelden",
"admin": "Admin",
"enabled": "Aktiviert",
"disabled": "Deaktiviert",
"reEnable": "Wieder aktivieren",
"disable": "Deaktivieren"
}, },
"notifications": { "notifications": {
"errorLoginBlank": "Der Benutzername und/oder das Passwort wurden nicht ausgefüllt.", "errorLoginBlank": "Der Benutzername und/oder das Passwort wurden nicht ausgefüllt.",
"errorConnection": "Konnte keine Verbindung zu jfa-go herstellen.", "errorConnection": "Konnte keine Verbindung zu jfa-go herstellen.",
"errorUnknown": "Unbekannter Fehler.", "errorUnknown": "Unbekannter Fehler.",
"error401Unauthorized": "Unberechtigt. Versuch, die Seite zu aktualisieren." "error401Unauthorized": "Unberechtigt. Versuch, die Seite zu aktualisieren.",
"errorSaveSettings": "Einstellungen konnten nicht gespeichert werden."
} }
} }

View File

@ -17,12 +17,18 @@
"time12h": "12 Ώρες", "time12h": "12 Ώρες",
"theme": "Θέμα", "theme": "Θέμα",
"login": "Σύνδεση", "login": "Σύνδεση",
"logout": "Αποσύνδεση" "logout": "Αποσύνδεση",
"admin": "Διαχειριστής",
"enabled": "Ενεργοποιημένο",
"disabled": "Απενεργοποιημένο",
"reEnable": "Επανα-ενεργοποίηση",
"disable": "Απενεργοποίηση"
}, },
"notifications": { "notifications": {
"errorLoginBlank": "Το όνομα χρήστη και/ή ο κωδικός ήταν κενά.", "errorLoginBlank": "Το όνομα χρήστη και/ή ο κωδικός ήταν κενά.",
"errorConnection": "Δεν μπόρεσε να συνδεθεί με το jfa-go.", "errorConnection": "Δεν μπόρεσε να συνδεθεί με το jfa-go.",
"errorUnknown": "Άγνωστο σφάλμα.", "errorUnknown": "Άγνωστο σφάλμα.",
"error401Unauthorized": "Ανεξουσιοδότητος. Προσπαθήστε να κάνετε επαναφόρτωση την σελίδα." "error401Unauthorized": "Ανεξουσιοδότητος. Προσπαθήστε να κάνετε επαναφόρτωση την σελίδα.",
"errorSaveSettings": "Αποτυχία αποθήκευσης ρυθμίσεων."
} }
} }

View File

@ -26,12 +26,18 @@
"refresh": "Refresh", "refresh": "Refresh",
"required": "Required", "required": "Required",
"login": "Login", "login": "Login",
"logout": "Logout" "logout": "Logout",
"admin": "Admin",
"enabled": "Enabled",
"disabled": "Disabled",
"reEnable": "Re-enable",
"disable": "Disable"
}, },
"notifications": { "notifications": {
"errorLoginBlank": "The username and/or password was left blank.", "errorLoginBlank": "The username and/or password was left blank.",
"errorConnection": "Couldn't connect to jfa-go.", "errorConnection": "Couldn't connect to jfa-go.",
"errorUnknown": "Unknown error.", "errorUnknown": "Unknown error.",
"error401Unauthorized": "Unauthorised. Try refreshing the page." "error401Unauthorized": "Unauthorised. Try refreshing the page.",
"errorSaveSettings": "Couldn't save settings."
} }
} }

View File

@ -26,12 +26,19 @@
"refresh": "Refresh", "refresh": "Refresh",
"required": "Required", "required": "Required",
"login": "Login", "login": "Login",
"logout": "Logout" "logout": "Logout",
"admin": "Admin",
"enabled": "Enabled",
"disabled": "Disabled",
"reEnable": "Re-enable",
"disable": "Disable",
"contactMethods": "Contact Methods"
}, },
"notifications": { "notifications": {
"errorLoginBlank": "The username and/or password were left blank.", "errorLoginBlank": "The username and/or password were left blank.",
"errorConnection": "Couldn't connect to jfa-go.", "errorConnection": "Couldn't connect to jfa-go.",
"errorUnknown": "Unknown error.", "errorUnknown": "Unknown error.",
"error401Unauthorized": "Unauthorized. Try refreshing the page." "error401Unauthorized": "Unauthorized. Try refreshing the page.",
"errorSaveSettings": "Couldn't save settings."
} }
} }

View File

@ -26,12 +26,18 @@
"refresh": "Refrescar", "refresh": "Refrescar",
"required": "Requerido", "required": "Requerido",
"login": "Acceso", "login": "Acceso",
"logout": "Cerrar sesión" "logout": "Cerrar sesión",
"admin": "Administrador",
"enabled": "Activado",
"disabled": "Desactivado",
"reEnable": "Reactivar",
"disable": "Desactivar"
}, },
"notifications": { "notifications": {
"errorLoginBlank": "El nombre de usuario y/o la contraseña se dejaron en blanco.", "errorLoginBlank": "El nombre de usuario y/o la contraseña se dejaron en blanco.",
"errorConnection": "No se pudo conectar a jfa-go.", "errorConnection": "No se pudo conectar a jfa-go.",
"errorUnknown": "Error desconocido.", "errorUnknown": "Error desconocido.",
"error401Unauthorized": "No autorizado. Intente actualizar la página." "error401Unauthorized": "No autorizado. Intente actualizar la página.",
"errorSaveSettings": "No se pudo guardar la configuración."
} }
} }

View File

@ -26,12 +26,18 @@
"refresh": "Actualiser", "refresh": "Actualiser",
"required": "Requis", "required": "Requis",
"login": "S'identifier", "login": "S'identifier",
"logout": "Se déconnecter" "logout": "Se déconnecter",
"admin": "Administrateur",
"enabled": "Activé",
"disabled": "Désactivé",
"reEnable": "Ré-activé",
"disable": "Désactivé"
}, },
"notifications": { "notifications": {
"errorLoginBlank": "Le nom d'utilisateur et/ou le mot de passe sont vides.", "errorLoginBlank": "Le nom d'utilisateur et/ou le mot de passe sont vides.",
"errorConnection": "Impossible de se connecter à jfa-go.", "errorConnection": "Impossible de se connecter à jfa-go.",
"errorUnknown": "Erreur inconnue.", "errorUnknown": "Erreur inconnue.",
"error401Unauthorized": "Non autorisé. Essayez d'actualiser la page." "error401Unauthorized": "Non autorisé. Essayez d'actualiser la page.",
"errorSaveSettings": "Impossible d'enregistrer les paramètres."
} }
} }

View File

@ -4,7 +4,12 @@
}, },
"strings": { "strings": {
"login": "Belépés", "login": "Belépés",
"logout": "Kijelentkezés" "logout": "Kijelentkezés",
"admin": "Adminisztrátor",
"enabled": "Engedélyezve",
"disabled": "Tiltva",
"reEnable": "Újra engedélyezés",
"disable": "Letiltás"
}, },
"notifications": {} "notifications": {}
} }

View File

@ -23,6 +23,7 @@
"errorLoginBlank": "Nama pengguna dan / atau sandi kosong.", "errorLoginBlank": "Nama pengguna dan / atau sandi kosong.",
"errorConnection": "Tidak dapat terhubung ke jfa-go.", "errorConnection": "Tidak dapat terhubung ke jfa-go.",
"errorUnknown": "Kesalahan yang tidak diketahui.", "errorUnknown": "Kesalahan yang tidak diketahui.",
"error401Unauthorized": "Tidak ter-otorisasi. Coba segarkan halaman." "error401Unauthorized": "Tidak ter-otorisasi. Coba segarkan halaman.",
"errorSaveSettings": "Tidak dapat menyimpan pengaturan."
} }
} }

View File

@ -26,12 +26,18 @@
"refresh": "Ververs", "refresh": "Ververs",
"required": "Verplicht", "required": "Verplicht",
"login": "Inloggen", "login": "Inloggen",
"logout": "Uitloggen" "logout": "Uitloggen",
"admin": "Beheerder",
"enabled": "Ingeschakeld",
"disabled": "Uitgeschakeld",
"reEnable": "Opnieuw inschakelen",
"disable": "Uitschakelen"
}, },
"notifications": { "notifications": {
"errorLoginBlank": "De gebruikersnaam en/of wachtwoord is leeg.", "errorLoginBlank": "De gebruikersnaam en/of wachtwoord is leeg.",
"errorConnection": "Kon geen verbinding maken met jfa-go.", "errorConnection": "Kon geen verbinding maken met jfa-go.",
"errorUnknown": "Onbekende fout.", "errorUnknown": "Onbekende fout.",
"error401Unauthorized": "Geen toegang. Probeer de pagina te vernieuwen." "error401Unauthorized": "Geen toegang. Probeer de pagina te vernieuwen.",
"errorSaveSettings": "Opslaan van instellingen mislukt."
} }
} }

View File

@ -24,7 +24,11 @@
"contactDiscord": "Kontakt przez Discord", "contactDiscord": "Kontakt przez Discord",
"theme": "Motyw", "theme": "Motyw",
"refresh": "Odśwież", "refresh": "Odśwież",
"required": "Wymagane" "required": "Wymagane",
"admin": "Admin",
"enabled": "Włączone",
"disabled": "Wyłączone",
"disable": "Wyłączone"
}, },
"notifications": { "notifications": {
"errorConnection": "Nie udało się połączyć z jfa-go.", "errorConnection": "Nie udało się połączyć z jfa-go.",

View File

@ -26,12 +26,18 @@
"refresh": "Atualizar", "refresh": "Atualizar",
"required": "Requeridos", "required": "Requeridos",
"login": "Login", "login": "Login",
"logout": "Sair" "logout": "Sair",
"admin": "Admin",
"enabled": "Habilitado",
"disabled": "Desativado",
"reEnable": "Reativar",
"disable": "Desativar"
}, },
"notifications": { "notifications": {
"errorLoginBlank": "O nome de usuário e/ou senha foram deixados em branco.", "errorLoginBlank": "O nome de usuário e/ou senha foram deixados em branco.",
"errorConnection": "Não foi possível conectar ao jfa-go.", "errorConnection": "Não foi possível conectar ao jfa-go.",
"errorUnknown": "Erro desconhecido.", "errorUnknown": "Erro desconhecido.",
"error401Unauthorized": "Não autorizado. Tente atualizar a página." "error401Unauthorized": "Não autorizado. Tente atualizar a página.",
"errorSaveSettings": "Não foi possível salvar as configurações."
} }
} }

View File

@ -16,12 +16,16 @@
"time12h": "12 timmarsklocka", "time12h": "12 timmarsklocka",
"theme": "Tema", "theme": "Tema",
"login": "Logga in", "login": "Logga in",
"logout": "Logga ut" "logout": "Logga ut",
"admin": "Admin",
"enabled": "Aktiverad",
"disabled": "Inaktiverad"
}, },
"notifications": { "notifications": {
"errorLoginBlank": "Användarnamnet och/eller lösenordet lämnades tomt.", "errorLoginBlank": "Användarnamnet och/eller lösenordet lämnades tomt.",
"errorConnection": "Det gick inte att ansluta till jfa-go.", "errorConnection": "Det gick inte att ansluta till jfa-go.",
"errorUnknown": "Okänt fel.", "errorUnknown": "Okänt fel.",
"error401Unauthorized": "Obehörig. Prova att uppdatera sidan." "error401Unauthorized": "Obehörig. Prova att uppdatera sidan.",
"errorSaveSettings": "Det gick inte att spara inställningarna."
} }
} }

View File

@ -4,7 +4,12 @@
}, },
"strings": { "strings": {
"login": "Đăng nhập", "login": "Đăng nhập",
"logout": "Đăng xuất" "logout": "Đăng xuất",
"admin": "Admin",
"enabled": "Mở",
"disabled": "Tắt",
"reEnable": "Mở lại",
"disable": "Tắt"
}, },
"notifications": { "notifications": {
"errorConnection": "Không thể kết nối với jfa-go.", "errorConnection": "Không thể kết nối với jfa-go.",

View File

@ -26,12 +26,18 @@
"refresh": "刷新", "refresh": "刷新",
"required": "必需的", "required": "必需的",
"login": "登录", "login": "登录",
"logout": "登出" "logout": "登出",
"admin": "管理员",
"enabled": "已启用",
"disabled": "已禁用",
"reEnable": "重新启用",
"disable": "禁用"
}, },
"notifications": { "notifications": {
"errorLoginBlank": "用户名/密码留空。", "errorLoginBlank": "用户名/密码留空。",
"errorConnection": "无法连接到 jfa-go。", "errorConnection": "无法连接到 jfa-go。",
"errorUnknown": "未知错误。", "errorUnknown": "未知错误。",
"error401Unauthorized": "无授权。尝试刷新页面。" "error401Unauthorized": "无授权。尝试刷新页面。",
"errorSaveSettings": "无法保存设置。"
} }
} }

View File

@ -26,12 +26,18 @@
"refresh": "重新整理", "refresh": "重新整理",
"required": "必填", "required": "必填",
"login": "登錄", "login": "登錄",
"logout": "登出" "logout": "登出",
"admin": "管理員",
"enabled": "已啟用",
"disabled": "已禁用",
"reEnable": "重新啟用",
"disable": "禁用"
}, },
"notifications": { "notifications": {
"errorLoginBlank": "帳戶名稱和/或密碼留空。", "errorLoginBlank": "帳戶名稱和/或密碼留空。",
"errorConnection": "無法連接到 jfa-go。", "errorConnection": "無法連接到 jfa-go。",
"errorUnknown": "未知的錯誤。", "errorUnknown": "未知的錯誤。",
"error401Unauthorized": "未經授權。嘗試重新整理頁面。" "error401Unauthorized": "未經授權。嘗試重新整理頁面。",
"errorSaveSettings": "無法儲存設置。"
} }
} }

View File

@ -20,7 +20,7 @@
"sendPIN": "Send the PIN below to the bot, then come back here to link your account.", "sendPIN": "Send the PIN below to the bot, then come back here to link your account.",
"sendPINDiscord": "Type {command} in {server_channel} on Discord, then send the PIN below.", "sendPINDiscord": "Type {command} in {server_channel} on Discord, then send the PIN below.",
"matrixEnterUser": "Enter your User ID, press submit, and a PIN will be sent to you. Enter it here to continue.", "matrixEnterUser": "Enter your User ID, press submit, and a PIN will be sent to you. Enter it here to continue.",
"welcomeUser": "Welcome, {user}" "welcomeUser": "Welcome, {user}!"
}, },
"notifications": { "notifications": {
"errorUserExists": "User already exists.", "errorUserExists": "User already exists.",

View File

@ -378,4 +378,16 @@ type ReCaptchaResponseDTO struct {
type MyDetailsDTO struct { type MyDetailsDTO struct {
Id string `json:"id"` Id string `json:"id"`
Username string `json:"username"` Username string `json:"username"`
Expiry int64 `json:"expiry"`
Admin bool `json:"admin"`
Disabled bool `json:"disabled"`
Email *MyDetailsContactMethodsDTO `json:"email,omitempty"`
Discord *MyDetailsContactMethodsDTO `json:"discord,omitempty"`
Telegram *MyDetailsContactMethodsDTO `json:"telegram,omitempty"`
Matrix *MyDetailsContactMethodsDTO `json:"matrix,omitempty"`
}
type MyDetailsContactMethodsDTO struct {
Value string `json:"value"`
Enabled bool `json:"enabled"`
} }

View File

@ -227,6 +227,8 @@ func (app *appContext) loadRoutes(router *gin.Engine) {
if userPageEnabled { if userPageEnabled {
user.GET(p+"/details", app.MyDetails) user.GET(p+"/details", app.MyDetails)
user.POST(p+"/contact", app.SetMyContactMethods)
user.POST(p+"/logout", app.LogoutUser)
} }
} }
} }

View File

@ -23,13 +23,19 @@
"theme": "common", "theme": "common",
"refresh": "common", "refresh": "common",
"required": "common", "required": "common",
"login": "admin", "login": "common",
"logout": "admin" "logout": "common",
"admin": "common",
"enabled": "common",
"disabled": "common",
"reEnable": "common",
"disable": "common"
}, },
"notifications": { "notifications": {
"errorLoginBlank": "admin", "errorLoginBlank": "common",
"errorConnection": "admin", "errorConnection": "common",
"errorUnknown": "admin", "errorUnknown": "common",
"error401Unauthorized": "admin" "error401Unauthorized": "common",
"errorSaveSettings": "admin"
} }
} }

View File

@ -144,6 +144,10 @@ func (st *Storage) loadLang(filesystems ...fs.FS) (err error) {
if err != nil { if err != nil {
return return
} }
err = st.loadLangEmail(filesystems...)
if err != nil {
return
}
err = st.loadLangUser(filesystems...) err = st.loadLangUser(filesystems...)
if err != nil { if err != nil {
return return
@ -152,10 +156,6 @@ func (st *Storage) loadLang(filesystems ...fs.FS) (err error) {
if err != nil { if err != nil {
return return
} }
err = st.loadLangEmail(filesystems...)
if err != nil {
return
}
err = st.loadLangTelegram(filesystems...) err = st.loadLangTelegram(filesystems...)
return return
} }
@ -437,6 +437,11 @@ func (st *Storage) loadLangUser(filesystems ...fs.FS) error {
} }
st.lang.Common.patchCommonStrings(&lang.Strings, index) st.lang.Common.patchCommonStrings(&lang.Strings, index)
st.lang.Common.patchCommonNotifications(&lang.Notifications, index) st.lang.Common.patchCommonNotifications(&lang.Notifications, index)
// turns out, a lot of email strings are useful on the user page.
emailLang := []langSection{st.lang.Email[index].WelcomeEmail, st.lang.Email[index].UserDisabled, st.lang.Email[index].UserExpired}
for _, v := range emailLang {
patchLang(&lang.Strings, &v)
}
if fname != "en-us.json" { if fname != "en-us.json" {
if lang.Meta.Fallback != "" { if lang.Meta.Fallback != "" {
fallback, ok := st.lang.User[lang.Meta.Fallback] fallback, ok := st.lang.User[lang.Meta.Fallback]

View File

@ -177,12 +177,6 @@ login.onLogin = () => {
} }
} }
login.login("", ""); login.bindLogout(document.getElementById("logout-button"));
(document.getElementById('logout-button') as HTMLButtonElement).onclick = () => _post("/logout", null, (req: XMLHttpRequest): boolean => { login.login("", "");
if (req.readyState == 4 && req.status == 200) {
window.token = "";
location.reload();
return false;
}
});

View File

@ -1,17 +1,17 @@
import { Modal } from "../modules/modal.js"; import { Modal } from "../modules/modal.js";
import { toggleLoader } from "../modules/common.js"; import { toggleLoader, _post } from "../modules/common.js";
export class Login { export class Login {
private _modal: Modal; private _modal: Modal;
private _form: HTMLFormElement; private _form: HTMLFormElement;
private _url: string; private _url: string;
private _onLogin: (username: string, password: string) => void; private _onLogin: (username: string, password: string) => void;
private _logoutButton: HTMLElement = null;
constructor(modal: Modal, endpoint: string) { constructor(modal: Modal, endpoint: string) {
this._url = window.URLBase + endpoint; this._url = window.URLBase + endpoint;
if (this._url[this._url.length-1] != '/') this._url += "/"; if (this._url[this._url.length-1] != '/') this._url += "/";
this._url += "token/";
this._modal = modal; this._modal = modal;
this._form = this._modal.asElement().querySelector(".form-login") as HTMLFormElement; this._form = this._modal.asElement().querySelector(".form-login") as HTMLFormElement;
@ -29,6 +29,18 @@ export class Login {
}; };
} }
bindLogout = (button: HTMLElement) => {
this._logoutButton = button;
this._logoutButton.classList.add("unfocused");
this._logoutButton.onclick = () => _post(this._url + "logout", null, (req: XMLHttpRequest): boolean => {
if (req.readyState == 4 && req.status == 200) {
window.token = "";
location.reload();
return false;
}
});
};
get onLogin() { return this._onLogin; } get onLogin() { return this._onLogin; }
set onLogin(f: (username: string, password: string) => void) { this._onLogin = f; } set onLogin(f: (username: string, password: string) => void) { this._onLogin = f; }
@ -36,7 +48,7 @@ export class Login {
const req = new XMLHttpRequest(); const req = new XMLHttpRequest();
req.responseType = 'json'; req.responseType = 'json';
const refresh = (username == "" && password == ""); const refresh = (username == "" && password == "");
req.open("GET", this._url + (refresh ? "refresh" : "login"), true); req.open("GET", this._url + (refresh ? "token/refresh" : "token/login"), true);
if (!refresh) { if (!refresh) {
req.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password)); req.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password));
} }
@ -46,6 +58,10 @@ export class Login {
let errorMsg = window.lang.notif("errorConnection"); let errorMsg = window.lang.notif("errorConnection");
if (req.response) { if (req.response) {
errorMsg = req.response["error"]; errorMsg = req.response["error"];
const langErrorMsg = window.lang.strings(errorMsg);
if (langErrorMsg) {
errorMsg = langErrorMsg;
}
} }
if (!errorMsg) { if (!errorMsg) {
errorMsg = window.lang.notif("errorUnknown"); errorMsg = window.lang.notif("errorUnknown");
@ -62,7 +78,8 @@ export class Login {
this._onLogin(username, password); this._onLogin(username, password);
} }
this._modal.close(); this._modal.close();
document.getElementById("logout-button").classList.remove("unfocused"); if (this._logoutButton != null)
this._logoutButton.classList.remove("unfocused");
} }
if (run) { run(+req.status); } if (run) { run(+req.status); }
} }

View File

@ -30,21 +30,167 @@ window.modals = {} as Modals;
window.notifications = new notificationBox(document.getElementById('notification-box') as HTMLDivElement, 5); window.notifications = new notificationBox(document.getElementById('notification-box') as HTMLDivElement, 5);
var rootCard = document.getElementById("card-user"); var rootCard = document.getElementById("card-user");
var contactCard = document.getElementById("card-contact");
const login = new Login(window.modals.login as Modal, "/my/"); interface MyDetailsContactMethod {
login.onLogin = () => { value: string;
console.log("Logged in."); enabled: boolean;
}
interface MyDetails {
id: string;
username: string;
expiry: number;
admin: boolean;
disabled: boolean;
email?: MyDetailsContactMethod;
discord?: MyDetailsContactMethod;
telegram?: MyDetailsContactMethod;
matrix?: MyDetailsContactMethod;
}
interface ContactDTO {
email?: boolean;
discord?: boolean;
telegram?: boolean;
matrix?: boolean;
}
class ContactMethods {
private _card: HTMLElement;
private _buttons: { [name: string]: { element: HTMLElement, details: MyDetailsContactMethod } };
constructor (card: HTMLElement) {
this._card = card;
this._buttons = {};
}
clear = () => {
this._card.textContent = "";
this._buttons = {};
}
append = (name: string, details: MyDetailsContactMethod, icon: string) => {
const row = document.createElement("div");
row.classList.add("row", "flex-expand", "my-2");
row.innerHTML = `
<div class="inline align-middle">
<span class="shield ~info" alt="${name}">
<span class="icon">
${icon}
</span>
</span>
<span class="ml-2 font-bold">${details.value}</span>
</div>
<div class="flex items-center">
<button class="user-contact-enabled-disabled button ~neutral">
<input type="checkbox" class="mr-2">
<span>${window.lang.strings("enabled")}</span>
</button>
</div>
`;
this._buttons[name] = {
element: row,
details: details
};
const button = row.querySelector(".user-contact-enabled-disabled") as HTMLButtonElement;
const checkbox = button.querySelector("input[type=checkbox]") as HTMLInputElement;
const setButtonAppearance = () => {
if (checkbox.checked) {
button.classList.add("~info");
button.classList.remove("~neutral");
} else {
button.classList.add("~neutral");
button.classList.remove("~info");
}
};
const onPress = () => {
this._buttons[name].details.enabled = checkbox.checked;
setButtonAppearance();
this._save();
};
checkbox.onchange = onPress;
button.onclick = () => {
checkbox.checked = !checkbox.checked;
onPress();
};
checkbox.checked = details.enabled;
setButtonAppearance();
this._card.appendChild(row);
};
private _save = () => {
let data: ContactDTO = {};
for (let method of Object.keys(this._buttons)) {
data[method] = this._buttons[method].details.enabled;
}
_post("/my/contact", data, (req: XMLHttpRequest) => {
if (req.readyState == 4) {
if (req.status != 200) {
window.notifications.customError("errorSetNotify", window.lang.notif("errorSaveSettings"));
document.dispatchEvent(new CustomEvent("details-reload"));
}
}
});
};
}
var contactMethodList = new ContactMethods(contactCard);
document.addEventListener("details-reload", () => {
_get("/my/details", null, (req: XMLHttpRequest) => { _get("/my/details", null, (req: XMLHttpRequest) => {
if (req.readyState == 4) { if (req.readyState == 4) {
if (req.status != 200) { if (req.status != 200) {
window.notifications.customError("myDetailsError", req.response["error"]); window.notifications.customError("myDetailsError", req.response["error"]);
return; return;
} }
window.jellyfinID = req.response["id"]; const details: MyDetails = req.response as MyDetails;
window.username = req.response["username"]; window.jellyfinID = details.id;
rootCard.querySelector(".heading").textContent = window.lang.strings("welcomeUser").replace("{user}", window.username); window.username = details.username;
let innerHTML = `
<span>${window.lang.strings("welcomeUser").replace("{user}", window.username)}</span>
`;
if (details.admin) {
innerHTML += `<span class="chip ~info ml-4">${window.lang.strings("admin")}</span>`;
}
if (details.disabled) {
innerHTML += `<span class="chip ~warning ml-4">${window.lang.strings("disabled")}</span>`;
}
rootCard.querySelector(".heading").innerHTML = innerHTML;
contactMethodList.clear();
const contactMethods = [
["email", `<i class="ri-mail-fill"></i>`],
["discord", `<i class="ri-discord-fill"></i>`],
["telegram", `<i class="ri-telegram-fill"></i>`],
["matrix", `[m]`]
];
for (let method of contactMethods) {
if (method[0] in details) {
contactMethodList.append(method[0], details[method[0]], method[1]);
}
}
} }
}); });
});
const login = new Login(window.modals.login as Modal, "/my/");
login.onLogin = () => {
console.log("Logged in.");
document.dispatchEvent(new CustomEvent("details-reload"));
}; };
login.bindLogout(document.getElementById("logout-button"));
login.login("", ""); login.login("", "");