mirror of
https://github.com/hrfee/jfa-go.git
synced 2024-12-22 17:10:10 +00:00
accounts: allow giving individual users jfa-go access
New "Access jfa-go" column allows you to select users for jfa-go access. New "Allow All" setting allows all Jellyfin users access, as disabling "Admin Only" no longer does this.
This commit is contained in:
parent
46d1da7cd3
commit
6448a7db9e
58
api.go
58
api.go
@ -1453,6 +1453,8 @@ func (app *appContext) GetUsers(gc *gin.Context) {
|
|||||||
respond(500, "Couldn't get users", gc)
|
respond(500, "Couldn't get users", gc)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
adminOnly := app.config.Section("ui").Key("admin_only").MustBool(true)
|
||||||
|
allowAll := app.config.Section("ui").Key("allow_all").MustBool(false)
|
||||||
i := 0
|
i := 0
|
||||||
app.storage.usersLock.Lock()
|
app.storage.usersLock.Lock()
|
||||||
defer app.storage.usersLock.Unlock()
|
defer app.storage.usersLock.Unlock()
|
||||||
@ -1470,6 +1472,7 @@ func (app *appContext) GetUsers(gc *gin.Context) {
|
|||||||
user.Email = email.Addr
|
user.Email = email.Addr
|
||||||
user.NotifyThroughEmail = email.Contact
|
user.NotifyThroughEmail = email.Contact
|
||||||
user.Label = email.Label
|
user.Label = email.Label
|
||||||
|
user.AccountsAdmin = (app.jellyfinLogin) && (email.Admin || (adminOnly && jfUser.Policy.IsAdministrator) || allowAll)
|
||||||
}
|
}
|
||||||
expiry, ok := app.storage.users[jfUser.ID]
|
expiry, ok := app.storage.users[jfUser.ID]
|
||||||
if ok {
|
if ok {
|
||||||
@ -1580,6 +1583,43 @@ func (app *appContext) DeleteOmbiProfile(gc *gin.Context) {
|
|||||||
respondBool(204, true, gc)
|
respondBool(204, true, gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Summary Set whether or not a user can access jfa-go. Redundant if the user is a Jellyfin admin.
|
||||||
|
// @Produce json
|
||||||
|
// @Param setAccountsAdminDTO body setAccountsAdminDTO true "Map of userIDs whether or not they have access."
|
||||||
|
// @Success 204 {object} boolResponse
|
||||||
|
// @Failure 500 {object} boolResponse
|
||||||
|
// @Router /users/accounts-admin [post]
|
||||||
|
// @Security Bearer
|
||||||
|
// @tags Users
|
||||||
|
func (app *appContext) SetAccountsAdmin(gc *gin.Context) {
|
||||||
|
var req setAccountsAdminDTO
|
||||||
|
gc.BindJSON(&req)
|
||||||
|
app.debug.Println("Admin modification requested")
|
||||||
|
users, status, err := app.jf.GetUsers(false)
|
||||||
|
if !(status == 200 || status == 204) || err != nil {
|
||||||
|
app.err.Printf("Failed to get users from Jellyfin (%d): %v", status, err)
|
||||||
|
respond(500, "Couldn't get users", gc)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, jfUser := range users {
|
||||||
|
id := jfUser.ID
|
||||||
|
if admin, ok := req[id]; ok {
|
||||||
|
var emailStore = EmailAddress{}
|
||||||
|
if oldEmail, ok := app.storage.emails[id]; ok {
|
||||||
|
emailStore = oldEmail
|
||||||
|
}
|
||||||
|
emailStore.Admin = admin
|
||||||
|
app.storage.emails[id] = emailStore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := app.storage.storeEmails(); err != nil {
|
||||||
|
app.err.Printf("Failed to store email list: %v", err)
|
||||||
|
respondBool(500, false, gc)
|
||||||
|
}
|
||||||
|
app.info.Println("Email list modified")
|
||||||
|
respondBool(204, true, gc)
|
||||||
|
}
|
||||||
|
|
||||||
// @Summary Modify user's labels, which show next to their name in the accounts tab.
|
// @Summary Modify user's labels, which show next to their name in the accounts tab.
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param modifyEmailsDTO body modifyEmailsDTO true "Map of userIDs to labels"
|
// @Param modifyEmailsDTO body modifyEmailsDTO true "Map of userIDs to labels"
|
||||||
@ -1601,13 +1641,12 @@ func (app *appContext) ModifyLabels(gc *gin.Context) {
|
|||||||
for _, jfUser := range users {
|
for _, jfUser := range users {
|
||||||
id := jfUser.ID
|
id := jfUser.ID
|
||||||
if label, ok := req[id]; ok {
|
if label, ok := req[id]; ok {
|
||||||
addr := ""
|
var emailStore = EmailAddress{}
|
||||||
contact := true
|
|
||||||
if oldEmail, ok := app.storage.emails[id]; ok {
|
if oldEmail, ok := app.storage.emails[id]; ok {
|
||||||
addr = oldEmail.Addr
|
emailStore = oldEmail
|
||||||
contact = oldEmail.Contact
|
|
||||||
}
|
}
|
||||||
app.storage.emails[id] = EmailAddress{Addr: addr, Contact: contact, Label: label}
|
emailStore.Label = label
|
||||||
|
app.storage.emails[id] = emailStore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := app.storage.storeEmails(); err != nil {
|
if err := app.storage.storeEmails(); err != nil {
|
||||||
@ -1640,11 +1679,12 @@ func (app *appContext) ModifyEmails(gc *gin.Context) {
|
|||||||
for _, jfUser := range users {
|
for _, jfUser := range users {
|
||||||
id := jfUser.ID
|
id := jfUser.ID
|
||||||
if address, ok := req[id]; ok {
|
if address, ok := req[id]; ok {
|
||||||
contact := true
|
var emailStore = EmailAddress{}
|
||||||
if oldAddr, ok := app.storage.emails[id]; ok {
|
if oldEmail, ok := app.storage.emails[id]; ok {
|
||||||
contact = oldAddr.Contact
|
emailStore = oldEmail
|
||||||
}
|
}
|
||||||
app.storage.emails[id] = EmailAddress{Addr: address, Contact: contact}
|
emailStore.Addr = address
|
||||||
|
app.storage.emails[id] = emailStore
|
||||||
if ombiEnabled {
|
if ombiEnabled {
|
||||||
ombiUser, code, err := app.getOmbiUser(id)
|
ombiUser, code, err := app.getOmbiUser(id)
|
||||||
if code == 200 && err == nil {
|
if code == 200 && err == nil {
|
||||||
|
10
auth.go
10
auth.go
@ -145,8 +145,14 @@ func (app *appContext) getTokenLogin(gc *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
jfID = user.ID
|
jfID = user.ID
|
||||||
if app.config.Section("ui").Key("admin_only").MustBool(true) {
|
if !app.config.Section("ui").Key("allow_all").MustBool(false) {
|
||||||
if !user.Policy.IsAdministrator {
|
accountsAdmin := false
|
||||||
|
adminOnly := app.config.Section("ui").Key("admin_only").MustBool(true)
|
||||||
|
if emailStore, ok := app.storage.emails[jfID]; ok {
|
||||||
|
accountsAdmin = emailStore.Admin
|
||||||
|
}
|
||||||
|
accountsAdmin = accountsAdmin || (adminOnly && user.Policy.IsAdministrator)
|
||||||
|
if !accountsAdmin {
|
||||||
app.debug.Printf("Auth denied: Users \"%s\" isn't admin", creds[0])
|
app.debug.Printf("Auth denied: Users \"%s\" isn't admin", creds[0])
|
||||||
respond(401, "Unauthorized", gc)
|
respond(401, "Unauthorized", gc)
|
||||||
return
|
return
|
||||||
|
@ -181,6 +181,15 @@
|
|||||||
"value": true,
|
"value": true,
|
||||||
"description": "Allows only admin users on Jellyfin to access the admin page."
|
"description": "Allows only admin users on Jellyfin to access the admin page."
|
||||||
},
|
},
|
||||||
|
"allow_all": {
|
||||||
|
"name": "Allow all users to login",
|
||||||
|
"required": false,
|
||||||
|
"requires_restart": true,
|
||||||
|
"depends_true": "jellyfin_login",
|
||||||
|
"type": "bool",
|
||||||
|
"value": false,
|
||||||
|
"description": "Allow all Jellyfin users to access jfa-go. Not recommended, add individual users in the Accounts tab instead."
|
||||||
|
},
|
||||||
"username": {
|
"username": {
|
||||||
"name": "Web Username",
|
"name": "Web Username",
|
||||||
"required": true,
|
"required": true,
|
||||||
|
@ -14,6 +14,9 @@
|
|||||||
window.langFile = JSON.parse({{ .language }});
|
window.langFile = JSON.parse({{ .language }});
|
||||||
window.linkResetEnabled = {{ .linkResetEnabled }};
|
window.linkResetEnabled = {{ .linkResetEnabled }};
|
||||||
window.language = "{{ .langName }}";
|
window.language = "{{ .langName }}";
|
||||||
|
window.jellyfinLogin = {{ .jellyfinLogin }};
|
||||||
|
window.jfAdminOnly = {{ .jfAdminOnly }};
|
||||||
|
window.jfAllowAll = {{ .jfAllowAll }};
|
||||||
</script>
|
</script>
|
||||||
<title>Admin - jfa-go</title>
|
<title>Admin - jfa-go</title>
|
||||||
{{ template "header.html" . }}
|
{{ template "header.html" . }}
|
||||||
@ -613,6 +616,9 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th><input type="checkbox" value="" id="accounts-select-all"></th>
|
<th><input type="checkbox" value="" id="accounts-select-all"></th>
|
||||||
<th class="table-inline my-2">{{ .strings.username }}</th>
|
<th class="table-inline my-2">{{ .strings.username }}</th>
|
||||||
|
{{ if .jellyfinLogin }}
|
||||||
|
<th class="text-center-i">{{ .strings.accessJFA }}</th>
|
||||||
|
{{ end }}
|
||||||
<th>{{ .strings.emailAddress }}</th>
|
<th>{{ .strings.emailAddress }}</th>
|
||||||
{{ if .telegramEnabled }}
|
{{ if .telegramEnabled }}
|
||||||
<th class="text-center-i">Telegram</th>
|
<th class="text-center-i">Telegram</th>
|
||||||
|
@ -139,6 +139,10 @@
|
|||||||
<label class="row switch pl-4 pb-4">
|
<label class="row switch pl-4 pb-4">
|
||||||
<input type="checkbox" class="mr-2" id="ui-admin_only"><span>{{ .lang.Login.adminOnly }}</span>
|
<input type="checkbox" class="mr-2" id="ui-admin_only"><span>{{ .lang.Login.adminOnly }}</span>
|
||||||
</label>
|
</label>
|
||||||
|
<label class="row switch pl-4 pb-2">
|
||||||
|
<input type="checkbox" class="mr-2" id="ui-allow_all"><span>{{ .lang.Login.allowAll }}</span>
|
||||||
|
</label>
|
||||||
|
<p class="support pb-4 pl-4 mt-1" id="description-ui-allow_all">{{ .lang.Login.allowAllDescription }}</p>
|
||||||
<label class="row switch pb-4">
|
<label class="row switch pb-4">
|
||||||
<input type="radio" class="mr-2" name="ui-jellyfin_login" value="false"><span>{{ .lang.Login.authorizeManual }}</span>
|
<input type="radio" class="mr-2" name="ui-jellyfin_login" value="false"><span>{{ .lang.Login.authorizeManual }}</span>
|
||||||
</label>
|
</label>
|
||||||
|
@ -111,7 +111,9 @@
|
|||||||
"matrixHomeServer": "Home server address",
|
"matrixHomeServer": "Home server address",
|
||||||
"saveAsTemplate": "Save as template",
|
"saveAsTemplate": "Save as template",
|
||||||
"deleteTemplate": "Delete template",
|
"deleteTemplate": "Delete template",
|
||||||
"templateEnterName": "Enter a name to save this template."
|
"templateEnterName": "Enter a name to save this template.",
|
||||||
|
"accessJFA": "Access jfa-go",
|
||||||
|
"accessJFASettings": "Cannot be changed as this either \"Admin Only\" or \"Allow All\" has been set in Settings > General."
|
||||||
},
|
},
|
||||||
"notifications": {
|
"notifications": {
|
||||||
"changedEmailAddress": "Changed email address of {n}.",
|
"changedEmailAddress": "Changed email address of {n}.",
|
||||||
|
@ -65,6 +65,8 @@
|
|||||||
"authorizeWithJellyfin": "Authorize with Jellyfin/Emby: Login details are shared with Jellyfin, which allows for multiple users.",
|
"authorizeWithJellyfin": "Authorize with Jellyfin/Emby: Login details are shared with Jellyfin, which allows for multiple users.",
|
||||||
"authorizeManual": "Username and Password: Manually set the username and password.",
|
"authorizeManual": "Username and Password: Manually set the username and password.",
|
||||||
"adminOnly": "Admin users only (recommended)",
|
"adminOnly": "Admin users only (recommended)",
|
||||||
|
"allowAll": "Allow all Jellyfin users to login",
|
||||||
|
"allowAllDescription": "Not recommended, you should allow individual users to login once setup.",
|
||||||
"emailNotice": "Your email address can be used to receive notifications."
|
"emailNotice": "Your email address can be used to receive notifications."
|
||||||
},
|
},
|
||||||
"jellyfinEmby": {
|
"jellyfinEmby": {
|
||||||
|
@ -146,6 +146,7 @@ type respUser struct {
|
|||||||
Matrix string `json:"matrix"` // Matrix ID (if known)
|
Matrix string `json:"matrix"` // Matrix ID (if known)
|
||||||
NotifyThroughMatrix bool `json:"notify_matrix"`
|
NotifyThroughMatrix bool `json:"notify_matrix"`
|
||||||
Label string `json:"label"` // Label of user, shown next to their name.
|
Label string `json:"label"` // Label of user, shown next to their name.
|
||||||
|
AccountsAdmin bool `json:"accounts_admin"` // Whether or not the user is a jfa-go admin.
|
||||||
}
|
}
|
||||||
|
|
||||||
type getUsersDTO struct {
|
type getUsersDTO struct {
|
||||||
@ -346,3 +347,5 @@ type InternalPWR struct {
|
|||||||
type LogDTO struct {
|
type LogDTO struct {
|
||||||
Log string `json:"log"`
|
Log string `json:"log"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type setAccountsAdminDTO map[string]bool
|
||||||
|
@ -161,6 +161,7 @@ func (app *appContext) loadRoutes(router *gin.Engine) {
|
|||||||
api.POST(p+"/invites/notify", app.SetNotify)
|
api.POST(p+"/invites/notify", app.SetNotify)
|
||||||
api.POST(p+"/users/emails", app.ModifyEmails)
|
api.POST(p+"/users/emails", app.ModifyEmails)
|
||||||
api.POST(p+"/users/labels", app.ModifyLabels)
|
api.POST(p+"/users/labels", app.ModifyLabels)
|
||||||
|
api.POST(p+"/users/accounts-admin", app.SetAccountsAdmin)
|
||||||
// api.POST(p + "/setDefaults", app.SetDefaults)
|
// api.POST(p + "/setDefaults", app.SetDefaults)
|
||||||
api.POST(p+"/users/settings", app.ApplySettings)
|
api.POST(p+"/users/settings", app.ApplySettings)
|
||||||
api.POST(p+"/users/announce", app.Announce)
|
api.POST(p+"/users/announce", app.Announce)
|
||||||
|
1
setup.go
1
setup.go
@ -38,6 +38,7 @@ func (app *appContext) ServeSetup(gc *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
gc.HTML(200, "setup.html", gin.H{
|
gc.HTML(200, "setup.html", gin.H{
|
||||||
|
"cssVersion": cssVersion,
|
||||||
"lang": app.storage.lang.Setup[lang],
|
"lang": app.storage.lang.Setup[lang],
|
||||||
"emailLang": app.storage.lang.Email[emailLang],
|
"emailLang": app.storage.lang.Email[emailLang],
|
||||||
"language": app.storage.lang.Setup[lang].JSON,
|
"language": app.storage.lang.Setup[lang].JSON,
|
||||||
|
@ -54,6 +54,7 @@ type EmailAddress struct {
|
|||||||
Addr string
|
Addr string
|
||||||
Label string // User Label.
|
Label string // User Label.
|
||||||
Contact bool
|
Contact bool
|
||||||
|
Admin bool // Whether or not user is jfa-go admin.
|
||||||
}
|
}
|
||||||
|
|
||||||
type customEmails struct {
|
type customEmails struct {
|
||||||
|
@ -21,6 +21,7 @@ interface User {
|
|||||||
matrix: string;
|
matrix: string;
|
||||||
notify_matrix: boolean;
|
notify_matrix: boolean;
|
||||||
label: string;
|
label: string;
|
||||||
|
accounts_admin: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface getPinResponse {
|
interface getPinResponse {
|
||||||
@ -64,6 +65,7 @@ class user implements User {
|
|||||||
private _label: HTMLInputElement;
|
private _label: HTMLInputElement;
|
||||||
private _userLabel: string;
|
private _userLabel: string;
|
||||||
private _labelEditButton: HTMLElement;
|
private _labelEditButton: HTMLElement;
|
||||||
|
private _accounts_admin: HTMLInputElement
|
||||||
id = "";
|
id = "";
|
||||||
private _selected: boolean;
|
private _selected: boolean;
|
||||||
|
|
||||||
@ -98,6 +100,18 @@ class user implements User {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get accounts_admin(): boolean { return this._accounts_admin.checked; }
|
||||||
|
set accounts_admin(a: boolean) {
|
||||||
|
if (!window.jellyfinLogin) return;
|
||||||
|
this._accounts_admin.checked = a;
|
||||||
|
this._accounts_admin.disabled = (window.jfAllowAll || (a && this.admin && window.jfAdminOnly));
|
||||||
|
if (this._accounts_admin.disabled) {
|
||||||
|
this._accounts_admin.title = window.lang.strings("accessJFASettings");
|
||||||
|
} else {
|
||||||
|
this._accounts_admin.title = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
get disabled(): boolean { return this._disabled.classList.contains("chip"); }
|
get disabled(): boolean { return this._disabled.classList.contains("chip"); }
|
||||||
set disabled(state: boolean) {
|
set disabled(state: boolean) {
|
||||||
if (state) {
|
if (state) {
|
||||||
@ -386,7 +400,6 @@ class user implements User {
|
|||||||
|
|
||||||
get label(): string { return this._userLabel; }
|
get label(): string { return this._userLabel; }
|
||||||
set label(l: string) {
|
set label(l: string) {
|
||||||
console.log(l);
|
|
||||||
this._userLabel = l ? l : "";
|
this._userLabel = l ? l : "";
|
||||||
this._label.innerHTML = l ? l : "";
|
this._label.innerHTML = l ? l : "";
|
||||||
this._labelEditButton.classList.add("ri-edit-line");
|
this._labelEditButton.classList.add("ri-edit-line");
|
||||||
@ -403,8 +416,15 @@ class user implements User {
|
|||||||
constructor(user: User) {
|
constructor(user: User) {
|
||||||
this._row = document.createElement("tr") as HTMLTableRowElement;
|
this._row = document.createElement("tr") as HTMLTableRowElement;
|
||||||
let innerHTML = `
|
let innerHTML = `
|
||||||
<td><input type="checkbox" value=""></td>
|
<td><input type="checkbox" class="accounts-select-user" value=""></td>
|
||||||
<td><div class="table-inline"><span class="accounts-username py-2 mr-2"></span><span class="accounts-label-container ml-2"></span> <i class="icon ri-edit-line accounts-label-edit"></i> <span class="accounts-admin"></span> <span class="accounts-disabled"></span></span></div></td>
|
<td><div class="table-inline"><span class="accounts-username py-2 mr-2"></span><span class="accounts-label-container ml-2"></span> <i class="icon ri-edit-line accounts-label-edit"></i> <span class="accounts-admin"></span> <span class="accounts-disabled"></span></span></div></td>
|
||||||
|
`;
|
||||||
|
if (window.jellyfinLogin) {
|
||||||
|
innerHTML += `
|
||||||
|
<td><div class="table-inline justify-center"><input type="checkbox" class="accounts-access-jfa" value=""></div></td>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
innerHTML += `
|
||||||
<td><div class="table-inline"><i class="icon ri-edit-line accounts-email-edit"></i><span class="accounts-email-container ml-2"></span></div></td>
|
<td><div class="table-inline"><i class="icon ri-edit-line accounts-email-edit"></i><span class="accounts-email-container ml-2"></span></div></td>
|
||||||
`;
|
`;
|
||||||
if (window.telegramEnabled) {
|
if (window.telegramEnabled) {
|
||||||
@ -429,7 +449,8 @@ class user implements User {
|
|||||||
this._row.innerHTML = innerHTML;
|
this._row.innerHTML = innerHTML;
|
||||||
const emailEditor = `<input type="email" class="input ~neutral @low stealth-input">`;
|
const emailEditor = `<input type="email" class="input ~neutral @low stealth-input">`;
|
||||||
const labelEditor = `<input type="text" class="field ~neutral @low stealth-input">`;
|
const labelEditor = `<input type="text" class="field ~neutral @low stealth-input">`;
|
||||||
this._check = this._row.querySelector("input[type=checkbox]") as HTMLInputElement;
|
this._check = this._row.querySelector("input[type=checkbox].accounts-select-user") as HTMLInputElement;
|
||||||
|
this._accounts_admin = this._row.querySelector("input[type=checkbox].accounts-access-jfa") as HTMLInputElement;
|
||||||
this._username = this._row.querySelector(".accounts-username") as HTMLSpanElement;
|
this._username = this._row.querySelector(".accounts-username") as HTMLSpanElement;
|
||||||
this._admin = this._row.querySelector(".accounts-admin") as HTMLSpanElement;
|
this._admin = this._row.querySelector(".accounts-admin") as HTMLSpanElement;
|
||||||
this._disabled = this._row.querySelector(".accounts-disabled") as HTMLSpanElement;
|
this._disabled = this._row.querySelector(".accounts-disabled") as HTMLSpanElement;
|
||||||
@ -444,6 +465,22 @@ class user implements User {
|
|||||||
this._labelEditButton = this._row.querySelector(".accounts-label-edit") as HTMLElement;
|
this._labelEditButton = this._row.querySelector(".accounts-label-edit") as HTMLElement;
|
||||||
this._check.onchange = () => { this.selected = this._check.checked; }
|
this._check.onchange = () => { this.selected = this._check.checked; }
|
||||||
|
|
||||||
|
if (window.jellyfinLogin) {
|
||||||
|
this._accounts_admin.onchange = () => {
|
||||||
|
this.accounts_admin = this._accounts_admin.checked;
|
||||||
|
let send = {};
|
||||||
|
send[this.id] = this.accounts_admin;
|
||||||
|
_post("/users/accounts-admin", send, (req: XMLHttpRequest) => {
|
||||||
|
if (req.readyState == 4) {
|
||||||
|
if (req.status != 204) {
|
||||||
|
this.accounts_admin = !this.accounts_admin;
|
||||||
|
window.notifications.customError("accountsAdminChanged", window.lang.notif("errorUnknown"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
this._notifyDropdown = this._constructDropdown();
|
this._notifyDropdown = this._constructDropdown();
|
||||||
|
|
||||||
const toggleEmailInput = () => {
|
const toggleEmailInput = () => {
|
||||||
@ -611,6 +648,7 @@ class user implements User {
|
|||||||
this.notify_email = user.notify_email;
|
this.notify_email = user.notify_email;
|
||||||
this.discord_id = user.discord_id;
|
this.discord_id = user.discord_id;
|
||||||
this.label = user.label;
|
this.label = user.label;
|
||||||
|
this.accounts_admin = user.accounts_admin;
|
||||||
}
|
}
|
||||||
|
|
||||||
asElement = (): HTMLTableRowElement => { return this._row; }
|
asElement = (): HTMLTableRowElement => { return this._row; }
|
||||||
@ -1145,7 +1183,6 @@ export class accountsList {
|
|||||||
let manualUser: user;
|
let manualUser: user;
|
||||||
for (let id of list) {
|
for (let id of list) {
|
||||||
let user = this._users[id];
|
let user = this._users[id];
|
||||||
console.log(user, user.notify_email, user.notify_matrix, user.notify_discord, user.notify_telegram);
|
|
||||||
if (!user.lastNotifyMethod() && !user.email) {
|
if (!user.lastNotifyMethod() && !user.email) {
|
||||||
manualUser = user;
|
manualUser = user;
|
||||||
break;
|
break;
|
||||||
|
26
ts/setup.ts
26
ts/setup.ts
@ -239,6 +239,7 @@ const settings = {
|
|||||||
"language-admin": new LangSelect("admin", get("ui-language-admin")),
|
"language-admin": new LangSelect("admin", get("ui-language-admin")),
|
||||||
"jellyfin_login": new BoolRadios("ui-jellyfin_login", "", false, "ui", "jellyfin_login"),
|
"jellyfin_login": new BoolRadios("ui-jellyfin_login", "", false, "ui", "jellyfin_login"),
|
||||||
"admin_only": new Checkbox(get("ui-admin_only"), "jellyfin_login", true, "ui"),
|
"admin_only": new Checkbox(get("ui-admin_only"), "jellyfin_login", true, "ui"),
|
||||||
|
"allow_all": new Checkbox(get("ui-allow_all"), "jellyfin_login", true, "ui"),
|
||||||
"username": new Input(get("ui-username"), "", "", "jellyfin_login", false, "ui"),
|
"username": new Input(get("ui-username"), "", "", "jellyfin_login", false, "ui"),
|
||||||
"password": new Input(get("ui-password"), "", "", "jellyfin_login", false, "ui"),
|
"password": new Input(get("ui-password"), "", "", "jellyfin_login", false, "ui"),
|
||||||
"email": new Input(get("ui-email"), "", "", "jellyfin_login", false, "ui"),
|
"email": new Input(get("ui-email"), "", "", "jellyfin_login", false, "ui"),
|
||||||
@ -389,6 +390,31 @@ settings["email"]["method"].onchange = emailMethodChange;
|
|||||||
settings["messages"]["enabled"].onchange = emailMethodChange;
|
settings["messages"]["enabled"].onchange = emailMethodChange;
|
||||||
emailMethodChange();
|
emailMethodChange();
|
||||||
|
|
||||||
|
const jellyfinLoginAccessChange = () => {
|
||||||
|
const adminOnly = settings["ui"]["admin_only"].value == "true";
|
||||||
|
const allowAll = settings["ui"]["allow_all"].value == "true";
|
||||||
|
const adminOnlyEl = document.getElementById("ui-admin_only") as HTMLInputElement;
|
||||||
|
const allowAllEls = [document.getElementById("ui-allow_all"), document.getElementById("description-ui-allow_all")];
|
||||||
|
const nextButton = adminOnlyEl.parentElement.parentElement.parentElement.querySelector("span.next") as HTMLSpanElement;
|
||||||
|
if (adminOnly && !allowAll) {
|
||||||
|
(allowAllEls[0] as HTMLInputElement).disabled = true;
|
||||||
|
adminOnlyEl.disabled = false;
|
||||||
|
nextButton.removeAttribute("disabled");
|
||||||
|
} else if (!adminOnly && allowAll) {
|
||||||
|
adminOnlyEl.disabled = true;
|
||||||
|
(allowAllEls[0] as HTMLInputElement).disabled = false;
|
||||||
|
nextButton.removeAttribute("disabled");
|
||||||
|
} else {
|
||||||
|
adminOnlyEl.disabled = false;
|
||||||
|
(allowAllEls[0] as HTMLInputElement).disabled = false;
|
||||||
|
nextButton.setAttribute("disabled", "true")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
settings["ui"]["admin_only"].onchange = jellyfinLoginAccessChange;
|
||||||
|
settings["ui"]["allow_all"].onchange = jellyfinLoginAccessChange;
|
||||||
|
jellyfinLoginAccessChange();
|
||||||
|
|
||||||
const embyHidePWR = () => {
|
const embyHidePWR = () => {
|
||||||
const pwr = document.getElementById("password-resets");
|
const pwr = document.getElementById("password-resets");
|
||||||
const val = settings["jellyfin"]["type"].value;
|
const val = settings["jellyfin"]["type"].value;
|
||||||
|
@ -37,6 +37,9 @@ declare interface Window {
|
|||||||
lang: Lang;
|
lang: Lang;
|
||||||
langFile: {};
|
langFile: {};
|
||||||
updater: updater;
|
updater: updater;
|
||||||
|
jellyfinLogin: boolean;
|
||||||
|
jfAdminOnly: boolean;
|
||||||
|
jfAllowAll: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare interface Update {
|
declare interface Update {
|
||||||
|
5
views.go
5
views.go
@ -110,6 +110,8 @@ func (app *appContext) AdminPage(gc *gin.Context) {
|
|||||||
emailEnabled, _ := app.config.Section("invite_emails").Key("enabled").Bool()
|
emailEnabled, _ := app.config.Section("invite_emails").Key("enabled").Bool()
|
||||||
notificationsEnabled, _ := app.config.Section("notifications").Key("enabled").Bool()
|
notificationsEnabled, _ := app.config.Section("notifications").Key("enabled").Bool()
|
||||||
ombiEnabled := app.config.Section("ombi").Key("enabled").MustBool(false)
|
ombiEnabled := app.config.Section("ombi").Key("enabled").MustBool(false)
|
||||||
|
jfAdminOnly := app.config.Section("ui").Key("admin_only").MustBool(true)
|
||||||
|
jfAllowAll := app.config.Section("ui").Key("allow_all").MustBool(false)
|
||||||
var license string
|
var license string
|
||||||
l, err := fs.ReadFile(localFS, "LICENSE")
|
l, err := fs.ReadFile(localFS, "LICENSE")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -137,6 +139,9 @@ func (app *appContext) AdminPage(gc *gin.Context) {
|
|||||||
"language": app.storage.lang.Admin[lang].JSON,
|
"language": app.storage.lang.Admin[lang].JSON,
|
||||||
"langName": lang,
|
"langName": lang,
|
||||||
"license": license,
|
"license": license,
|
||||||
|
"jellyfinLogin": app.jellyfinLogin,
|
||||||
|
"jfAdminOnly": jfAdminOnly,
|
||||||
|
"jfAllowAll": jfAllowAll,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user