mirror of
https://github.com/hrfee/jfa-go.git
synced 2024-12-29 12:30:11 +00:00
Compare commits
No commits in common. "c0c91b4aad41c5f50246286056aa57dbc5585b3d" and "10c8d4ad2f66d085e43b5a074a5af1e018282def" have entirely different histories.
c0c91b4aad
...
10c8d4ad2f
@ -131,9 +131,6 @@ steps:
|
|||||||
volumes:
|
volumes:
|
||||||
- name: ssh_key
|
- name: ssh_key
|
||||||
path: /root/drone_rsa
|
path: /root/drone_rsa
|
||||||
environment:
|
|
||||||
BUILDRONE_KEY:
|
|
||||||
from_secret: BUILDRONE_KEY
|
|
||||||
settings:
|
settings:
|
||||||
host:
|
host:
|
||||||
from_secret: ssh2_host
|
from_secret: ssh2_host
|
||||||
@ -143,15 +140,13 @@ steps:
|
|||||||
from_secret: ssh2_port
|
from_secret: ssh2_port
|
||||||
volumes:
|
volumes:
|
||||||
- /root/.ssh/docker-build:/root/drone_rsa
|
- /root/.ssh/docker-build:/root/drone_rsa
|
||||||
envs:
|
|
||||||
- buildrone_key
|
|
||||||
key_path: /root/drone_rsa
|
key_path: /root/drone_rsa
|
||||||
command_timeout: 50m
|
command_timeout: 50m
|
||||||
script:
|
script:
|
||||||
- /mnt/buildx/jfa-go/build.sh
|
- /mnt/buildx/jfa-go/build.sh
|
||||||
- wget https://builds.hrfee.pw/upload.py -O /mnt/buildx/jfa-go/jfa-go/upload.py
|
- wget https://builds.hrfee.pw/upload.py -O /mnt/buildx/jfa-go/jfa-go/upload.py
|
||||||
- pip3 install requests
|
- pip3 install requests
|
||||||
- bash -c 'cd /mnt/buildx/jfa-go/jfa-go && python3 upload.py https://builds.hrfee.pw hrfee jfa-go --tag docker-unstable=true'
|
- bash -c 'cd /mnt/buildx/jfa-go/jfa-go && BUILDRONE_KEY=$(cat /mnt/buildx/jfa-go/key) python3 upload.py https://builds.hrfee.pw hrfee jfa-go --tag docker-unstable=true'
|
||||||
- rm -f /mnt/buildx/jfa-go/jfa-go/upload.py
|
- rm -f /mnt/buildx/jfa-go/jfa-go/upload.py
|
||||||
trigger:
|
trigger:
|
||||||
branch:
|
branch:
|
||||||
|
@ -29,7 +29,6 @@ before:
|
|||||||
- npx esbuild --target=es6 --bundle tempts/admin.ts {{.Env.JFA_GO_SOURCEMAP}} --outfile=./data/web/js/admin.js {{.Env.JFA_GO_MINIFY}}
|
- npx esbuild --target=es6 --bundle tempts/admin.ts {{.Env.JFA_GO_SOURCEMAP}} --outfile=./data/web/js/admin.js {{.Env.JFA_GO_MINIFY}}
|
||||||
- npx esbuild --target=es6 --bundle tempts/user.ts {{.Env.JFA_GO_SOURCEMAP}} --outfile=./data/web/js/user.js {{.Env.JFA_GO_MINIFY}}
|
- npx esbuild --target=es6 --bundle tempts/user.ts {{.Env.JFA_GO_SOURCEMAP}} --outfile=./data/web/js/user.js {{.Env.JFA_GO_MINIFY}}
|
||||||
- npx esbuild --target=es6 --bundle tempts/pwr.ts {{.Env.JFA_GO_SOURCEMAP}} --outfile=./data/web/js/pwr.js {{.Env.JFA_GO_MINIFY}}
|
- npx esbuild --target=es6 --bundle tempts/pwr.ts {{.Env.JFA_GO_SOURCEMAP}} --outfile=./data/web/js/pwr.js {{.Env.JFA_GO_MINIFY}}
|
||||||
- npx esbuild --target=es6 --bundle tempts/pwr-pin.ts {{.Env.JFA_GO_SOURCEMAP}} --outfile=./data/web/js/pwr-pin.js {{.Env.JFA_GO_MINIFY}}
|
|
||||||
- npx esbuild --target=es6 --bundle tempts/form.ts {{.Env.JFA_GO_SOURCEMAP}} --outfile=./data/web/js/form.js {{.Env.JFA_GO_MINIFY}}
|
- npx esbuild --target=es6 --bundle tempts/form.ts {{.Env.JFA_GO_SOURCEMAP}} --outfile=./data/web/js/form.js {{.Env.JFA_GO_MINIFY}}
|
||||||
- npx esbuild --target=es6 --bundle tempts/setup.ts {{.Env.JFA_GO_SOURCEMAP}} --outfile=./data/web/js/setup.js {{.Env.JFA_GO_MINIFY}}
|
- npx esbuild --target=es6 --bundle tempts/setup.ts {{.Env.JFA_GO_SOURCEMAP}} --outfile=./data/web/js/setup.js {{.Env.JFA_GO_MINIFY}}
|
||||||
- npx esbuild --target=es6 --bundle tempts/crash.ts {{.Env.JFA_GO_SOURCEMAP}} --outfile=./data/crash.js {{.Env.JFA_GO_MINIFY}}
|
- npx esbuild --target=es6 --bundle tempts/crash.ts {{.Env.JFA_GO_SOURCEMAP}} --outfile=./data/crash.js {{.Env.JFA_GO_MINIFY}}
|
||||||
|
1
Makefile
1
Makefile
@ -121,7 +121,6 @@ typescript:
|
|||||||
$(ESBUILD) --target=es6 --bundle tempts/admin.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/admin.js --minify
|
$(ESBUILD) --target=es6 --bundle tempts/admin.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/admin.js --minify
|
||||||
$(ESBUILD) --target=es6 --bundle tempts/user.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/user.js --minify
|
$(ESBUILD) --target=es6 --bundle tempts/user.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/user.js --minify
|
||||||
$(ESBUILD) --target=es6 --bundle tempts/pwr.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/pwr.js --minify
|
$(ESBUILD) --target=es6 --bundle tempts/pwr.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/pwr.js --minify
|
||||||
$(ESBUILD) --target=es6 --bundle tempts/pwr-pin.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/pwr-pin.js --minify
|
|
||||||
$(ESBUILD) --target=es6 --bundle tempts/form.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/form.js --minify
|
$(ESBUILD) --target=es6 --bundle tempts/form.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/form.js --minify
|
||||||
$(ESBUILD) --target=es6 --bundle tempts/setup.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/setup.js --minify
|
$(ESBUILD) --target=es6 --bundle tempts/setup.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/setup.js --minify
|
||||||
$(ESBUILD) --target=es6 --bundle tempts/crash.ts --outfile=./$(DATA)/crash.js --minify
|
$(ESBUILD) --target=es6 --bundle tempts/crash.ts --outfile=./$(DATA)/crash.js --minify
|
||||||
|
@ -590,9 +590,6 @@ func (app *appContext) ResetMyPassword(gc *gin.Context) {
|
|||||||
cancel := time.AfterFunc(1*time.Second, func() {
|
cancel := time.AfterFunc(1*time.Second, func() {
|
||||||
timerWait <- true
|
timerWait <- true
|
||||||
})
|
})
|
||||||
usernameAllowed := app.config.Section("user_page").Key("allow_pwr_username").MustBool(true)
|
|
||||||
emailAllowed := app.config.Section("user_page").Key("allow_pwr_email").MustBool(true)
|
|
||||||
contactMethodAllowed := app.config.Section("user_page").Key("allow_pwr_contact_method").MustBool(true)
|
|
||||||
address := gc.Param("address")
|
address := gc.Param("address")
|
||||||
if address == "" {
|
if address == "" {
|
||||||
app.debug.Println("Ignoring empty request for PWR")
|
app.debug.Println("Ignoring empty request for PWR")
|
||||||
@ -603,7 +600,7 @@ func (app *appContext) ResetMyPassword(gc *gin.Context) {
|
|||||||
var pwr InternalPWR
|
var pwr InternalPWR
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
jfUser, ok := app.ReverseUserSearch(address, usernameAllowed, emailAllowed, contactMethodAllowed)
|
jfUser, ok := app.ReverseUserSearch(address)
|
||||||
if !ok {
|
if !ok {
|
||||||
app.debug.Printf("Ignoring PWR request: User not found")
|
app.debug.Printf("Ignoring PWR request: User not found")
|
||||||
|
|
||||||
|
@ -719,7 +719,7 @@ func (app *appContext) ExtendExpiry(gc *gin.Context) {
|
|||||||
var req extendExpiryDTO
|
var req extendExpiryDTO
|
||||||
gc.BindJSON(&req)
|
gc.BindJSON(&req)
|
||||||
app.info.Printf("Expiry extension requested for %d user(s)", len(req.Users))
|
app.info.Printf("Expiry extension requested for %d user(s)", len(req.Users))
|
||||||
if req.Months <= 0 && req.Days <= 0 && req.Hours <= 0 && req.Minutes <= 0 && req.Timestamp <= 0 {
|
if req.Months <= 0 && req.Days <= 0 && req.Hours <= 0 && req.Minutes <= 0 {
|
||||||
respondBool(400, false, gc)
|
respondBool(400, false, gc)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -731,12 +731,7 @@ func (app *appContext) ExtendExpiry(gc *gin.Context) {
|
|||||||
} else {
|
} else {
|
||||||
app.debug.Printf("Created expiry for \"%s\"", id)
|
app.debug.Printf("Created expiry for \"%s\"", id)
|
||||||
}
|
}
|
||||||
expiry := UserExpiry{}
|
expiry := UserExpiry{Expiry: base.AddDate(0, req.Months, req.Days).Add(time.Duration(((60 * req.Hours) + req.Minutes)) * time.Minute)}
|
||||||
if req.Timestamp != 0 {
|
|
||||||
expiry.Expiry = time.Unix(req.Timestamp, 0)
|
|
||||||
} else {
|
|
||||||
expiry.Expiry = base.AddDate(0, req.Months, req.Days).Add(time.Duration(((60 * req.Hours) + req.Minutes)) * time.Minute)
|
|
||||||
}
|
|
||||||
app.storage.SetUserExpiryKey(id, expiry)
|
app.storage.SetUserExpiryKey(id, expiry)
|
||||||
}
|
}
|
||||||
respondBool(204, true, gc)
|
respondBool(204, true, gc)
|
||||||
|
14
config.go
14
config.go
@ -122,20 +122,6 @@ func (app *appContext) loadConfig() error {
|
|||||||
app.MustSetValue("password_resets", "url_base", strings.TrimSuffix(url1, "/invite"))
|
app.MustSetValue("password_resets", "url_base", strings.TrimSuffix(url1, "/invite"))
|
||||||
app.MustSetValue("invite_emails", "url_base", url2)
|
app.MustSetValue("invite_emails", "url_base", url2)
|
||||||
|
|
||||||
pwrMethods := []string{"allow_pwr_username", "allow_pwr_email", "allow_pwr_contact_method"}
|
|
||||||
allDisabled := true
|
|
||||||
for _, v := range pwrMethods {
|
|
||||||
if app.config.Section("user_page").Key(v).MustBool(true) {
|
|
||||||
allDisabled = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if allDisabled {
|
|
||||||
fmt.Println("SETALLTRUE")
|
|
||||||
for _, v := range pwrMethods {
|
|
||||||
app.config.Section("user_page").Key(v).SetValue("true")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
messagesEnabled = app.config.Section("messages").Key("enabled").MustBool(false)
|
messagesEnabled = app.config.Section("messages").Key("enabled").MustBool(false)
|
||||||
telegramEnabled = app.config.Section("telegram").Key("enabled").MustBool(false)
|
telegramEnabled = app.config.Section("telegram").Key("enabled").MustBool(false)
|
||||||
discordEnabled = app.config.Section("discord").Key("enabled").MustBool(false)
|
discordEnabled = app.config.Section("discord").Key("enabled").MustBool(false)
|
||||||
|
@ -629,7 +629,6 @@
|
|||||||
"name": "Show Link on Admin Login page",
|
"name": "Show Link on Admin Login page",
|
||||||
"required": false,
|
"required": false,
|
||||||
"requires_restart": false,
|
"requires_restart": false,
|
||||||
"depends_true": "enabled",
|
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
"value": true,
|
"value": true,
|
||||||
"description": "Whether or not to show a link to the \"My Account\" page on the admin login screen, to direct lost users."
|
"description": "Whether or not to show a link to the \"My Account\" page on the admin login screen, to direct lost users."
|
||||||
@ -638,7 +637,6 @@
|
|||||||
"name": "User Referrals",
|
"name": "User Referrals",
|
||||||
"required": false,
|
"required": false,
|
||||||
"requires_restart": true,
|
"requires_restart": true,
|
||||||
"depends_true": "enabled",
|
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
"value": true,
|
"value": true,
|
||||||
"description": "Users are given their own \"invite\" to send to others."
|
"description": "Users are given their own \"invite\" to send to others."
|
||||||
@ -650,41 +648,6 @@
|
|||||||
"depends_true": "referrals",
|
"depends_true": "referrals",
|
||||||
"required": "false",
|
"required": "false",
|
||||||
"description": "Create an invite with your desired settings, then either assign it to a user in the accounts tab, or to a profile in settings."
|
"description": "Create an invite with your desired settings, then either assign it to a user in the accounts tab, or to a profile in settings."
|
||||||
},
|
|
||||||
"allow_pwr_username": {
|
|
||||||
"name": "Allow PWR with username",
|
|
||||||
"required": false,
|
|
||||||
"requires_restart": true,
|
|
||||||
"depends_true": "enabled",
|
|
||||||
"type": "bool",
|
|
||||||
"value": true,
|
|
||||||
"description": "Allow users to start a Password Reset by inputting their username."
|
|
||||||
},
|
|
||||||
"allow_pwr_email": {
|
|
||||||
"name": "Allow PWR with email address",
|
|
||||||
"required": false,
|
|
||||||
"requires_restart": true,
|
|
||||||
"depends_true": "enabled",
|
|
||||||
"type": "bool",
|
|
||||||
"value": true,
|
|
||||||
"description": "Allow users to start a Password Reset by inputting their email address."
|
|
||||||
},
|
|
||||||
"allow_pwr_contact_method": {
|
|
||||||
"name": "Allow PWR with Discord/Telegram/Matrix",
|
|
||||||
"required": false,
|
|
||||||
"requires_restart": true,
|
|
||||||
"depends_true": "enabled",
|
|
||||||
"type": "bool",
|
|
||||||
"value": true,
|
|
||||||
"description": "Allow users to start a Password Reset by inputting their Discord/Telegram/Matrix username/id."
|
|
||||||
},
|
|
||||||
"pwr_note": {
|
|
||||||
"name": "PWR Methods",
|
|
||||||
"type": "note",
|
|
||||||
"depends_true": "enabled",
|
|
||||||
"value": "",
|
|
||||||
"required": "false",
|
|
||||||
"description": "Select at least one PWR initiation method. If none are selected, all will be enabled."
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
14
email.go
14
email.go
@ -899,19 +899,13 @@ func (app *appContext) getAddressOrName(jfID string) string {
|
|||||||
|
|
||||||
// ReverseUserSearch returns the jellyfin ID of the user with the given username, email, or contact method username.
|
// ReverseUserSearch returns the jellyfin ID of the user with the given username, email, or contact method username.
|
||||||
// returns "" if none found. returns only the first match, might be an issue if there are users with the same contact method usernames.
|
// returns "" if none found. returns only the first match, might be an issue if there are users with the same contact method usernames.
|
||||||
func (app *appContext) ReverseUserSearch(address string, matchUsername, matchEmail, matchContactMethod bool) (user mediabrowser.User, ok bool) {
|
func (app *appContext) ReverseUserSearch(address string) (user mediabrowser.User, ok bool) {
|
||||||
ok = false
|
ok = false
|
||||||
var status int
|
user, status, err := app.jf.UserByName(address, false)
|
||||||
var err error = nil
|
|
||||||
if matchUsername {
|
|
||||||
user, status, err = app.jf.UserByName(address, false)
|
|
||||||
if status == 200 && err == nil {
|
if status == 200 && err == nil {
|
||||||
ok = true
|
ok = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if matchEmail {
|
|
||||||
emailAddresses := []EmailAddress{}
|
emailAddresses := []EmailAddress{}
|
||||||
err = app.storage.db.Find(&emailAddresses, badgerhold.Where("Addr").Eq(address))
|
err = app.storage.db.Find(&emailAddresses, badgerhold.Where("Addr").Eq(address))
|
||||||
if err == nil && len(emailAddresses) > 0 {
|
if err == nil && len(emailAddresses) > 0 {
|
||||||
@ -923,11 +917,8 @@ func (app *appContext) ReverseUserSearch(address string, matchUsername, matchEma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Dont know how we'd use badgerhold when we need to render each username,
|
// Dont know how we'd use badgerhold when we need to render each username,
|
||||||
// Apart from storing the rendered name in the db.
|
// Apart from storing the rendered name in the db.
|
||||||
if matchContactMethod {
|
|
||||||
for _, dcUser := range app.storage.GetDiscord() {
|
for _, dcUser := range app.storage.GetDiscord() {
|
||||||
if RenderDiscordUsername(dcUser) == strings.ToLower(address) {
|
if RenderDiscordUsername(dcUser) == strings.ToLower(address) {
|
||||||
user, status, err = app.jf.UserByID(dcUser.JellyfinID, false)
|
user, status, err = app.jf.UserByID(dcUser.JellyfinID, false)
|
||||||
@ -960,7 +951,6 @@ func (app *appContext) ReverseUserSearch(address string, matchUsername, matchEma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,15 +181,6 @@
|
|||||||
<form class="card relative mx-auto my-[10%] w-4/5 lg:w-1/3" id="form-extend-expiry" href="">
|
<form class="card relative mx-auto my-[10%] w-4/5 lg:w-1/3" id="form-extend-expiry" href="">
|
||||||
<span class="heading"><span id="header-extend-expiry"></span> <span class="modal-close">×</span></span>
|
<span class="heading"><span id="header-extend-expiry"></span> <span class="modal-close">×</span></span>
|
||||||
<div class="content mt-8">
|
<div class="content mt-8">
|
||||||
<aside class="aside sm ~urge dark:~d_info mb-2 @low row unfocused" id="extend-expiry-date"></aside>
|
|
||||||
<div>
|
|
||||||
<span class="text-xl supra row py-1">{{ .strings.setExpiry }}</span>
|
|
||||||
<div class="row">
|
|
||||||
<input type="text" id="extend-expiry-text" class="input ~neutral @low mb-2 mt-4" placeholder="{{ .strings.enterExpiry }}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="extend-expiry-field-inputs">
|
|
||||||
<span class="text-xl supra row py-1">{{ .strings.extendExpiry }}</span>
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<label class="label supra" for="extend-expiry-months">{{ .strings.inviteMonths }}</label>
|
<label class="label supra" for="extend-expiry-months">{{ .strings.inviteMonths }}</label>
|
||||||
@ -226,7 +217,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<label class="switch mb-4">
|
<label class="switch mb-4">
|
||||||
<input type="checkbox" id="expiry-extend-enable" checked>
|
<input type="checkbox" id="expiry-extend-enable" checked>
|
||||||
<span>{{ .strings.sendDeleteNotificationEmail }}</span>
|
<span>{{ .strings.sendDeleteNotificationEmail }}</span>
|
||||||
|
@ -48,17 +48,11 @@
|
|||||||
</div>
|
</div>
|
||||||
{{ if .pwrEnabled }}
|
{{ if .pwrEnabled }}
|
||||||
<div id="modal-pwr" class="modal">
|
<div id="modal-pwr" class="modal">
|
||||||
<div class="card content relative mx-auto my-[10%] w-4/5 lg:w-1/3 ~neutral @low">
|
<div class="card relative mx-auto my-[10%] w-4/5 lg:w-1/3 ~neutral @low">
|
||||||
<span class="heading">{{ .strings.resetPassword }}</span>
|
<span class="heading">{{ .strings.resetPassword }}</span>
|
||||||
<p class="content my-2">
|
<p class="content my-2">
|
||||||
{{ if .linkResetEnabled }}
|
{{ if .linkResetEnabled }}
|
||||||
{{ .strings.resetPasswordThroughLinkStart }}
|
{{ .strings.resetPasswordThroughLink }}
|
||||||
<ul class="content">
|
|
||||||
{{ if .resetPasswordUsername }}<li>{{ .strings.resetPasswordUsername }}</li>{{ end }}
|
|
||||||
{{ if .resetPasswordEmail }}<li>{{ .strings.resetPasswordEmail }}</li>{{ end }}
|
|
||||||
{{ if .resetPasswordContactMethod }}<li>{{ .strings.resetPasswordContactMethod }}</li>{{ end }}
|
|
||||||
</ul>
|
|
||||||
{{ .strings.resetPasswordThroughLinkEnd }}
|
|
||||||
{{ else }}
|
{{ else }}
|
||||||
{{ .strings.resetPasswordThroughJellyfin }}
|
{{ .strings.resetPasswordThroughJellyfin }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
@ -64,7 +64,6 @@
|
|||||||
"extendExpiry": "Extend expiry",
|
"extendExpiry": "Extend expiry",
|
||||||
"setExpiry": "Set expiry",
|
"setExpiry": "Set expiry",
|
||||||
"removeExpiry": "Remove expiry",
|
"removeExpiry": "Remove expiry",
|
||||||
"enterExpiry": "Enter an expiry",
|
|
||||||
"sendPWRManual": "User {n} has no method of contact, press copy to get a link to send to them.",
|
"sendPWRManual": "User {n} has no method of contact, press copy to get a link to send to them.",
|
||||||
"sendPWRSuccess": "Password reset link sent.",
|
"sendPWRSuccess": "Password reset link sent.",
|
||||||
"sendPWRSuccessManual": "If the user hasn't received it, press copy to get a link to manually send to them.",
|
"sendPWRSuccessManual": "If the user hasn't received it, press copy to get a link to manually send to them.",
|
||||||
@ -150,7 +149,6 @@
|
|||||||
"accountDisabled": "Account disabled: {user}",
|
"accountDisabled": "Account disabled: {user}",
|
||||||
"accountReEnabled": "Account re-enabled: {user}",
|
"accountReEnabled": "Account re-enabled: {user}",
|
||||||
"accountExpired": "Account expired: {user}",
|
"accountExpired": "Account expired: {user}",
|
||||||
"accountWillExpire": "Account will expire on {date}",
|
|
||||||
"userDeleted": "User was deleted.",
|
"userDeleted": "User was deleted.",
|
||||||
"userDisabled": "User was disabled",
|
"userDisabled": "User was disabled",
|
||||||
"inviteCreated": "Invite created: {invite}",
|
"inviteCreated": "Invite created: {invite}",
|
||||||
@ -221,7 +219,6 @@
|
|||||||
"errorCheckUpdate": "Failed to check for update.",
|
"errorCheckUpdate": "Failed to check for update.",
|
||||||
"errorNoReferralTemplate": "Profile doesn't contain referral template, add one in settings.",
|
"errorNoReferralTemplate": "Profile doesn't contain referral template, add one in settings.",
|
||||||
"errorLoadActivities": "Failed to load activities.",
|
"errorLoadActivities": "Failed to load activities.",
|
||||||
"errorInvalidDate": "Date is invalid.",
|
|
||||||
"updateAvailable": "A new update is available, check settings.",
|
"updateAvailable": "A new update is available, check settings.",
|
||||||
"noUpdatesAvailable": "No new updates available."
|
"noUpdatesAvailable": "No new updates available."
|
||||||
},
|
},
|
||||||
|
@ -32,11 +32,6 @@
|
|||||||
"resetPassword": "Reset Password",
|
"resetPassword": "Reset Password",
|
||||||
"resetPasswordThroughJellyfin": "To reset your password, visit {jfLink} and press the \"Forgot Password\" button.",
|
"resetPasswordThroughJellyfin": "To reset your password, visit {jfLink} and press the \"Forgot Password\" button.",
|
||||||
"resetPasswordThroughLink": "To reset your password, enter your username, email address or a linked contact method username, and submit. A link will be sent to reset your password.",
|
"resetPasswordThroughLink": "To reset your password, enter your username, email address or a linked contact method username, and submit. A link will be sent to reset your password.",
|
||||||
"resetPasswordThroughLinkStart": "To reset your password, enter one of the following below:",
|
|
||||||
"resetPasswordThroughLinkEnd": "Then press submit. A link will be sent to reset your password.",
|
|
||||||
"resetPasswordUsername": "Your Jellyfin username",
|
|
||||||
"resetPasswordEmail": "Your email address",
|
|
||||||
"resetPasswordContactMethod": "The username of any contact method linked to your account",
|
|
||||||
"resetSent": "Reset Sent.",
|
"resetSent": "Reset Sent.",
|
||||||
"resetSentDescription": "If an account with the given username/contact method exists, a password reset link has been sent via all contact methods available. The code will expire in 30 minutes.",
|
"resetSentDescription": "If an account with the given username/contact method exists, a password reset link has been sent via all contact methods available. The code will expire in 30 minutes.",
|
||||||
"changePassword": "Change Password",
|
"changePassword": "Change Password",
|
||||||
|
@ -49,7 +49,7 @@ func Lshortfile(level int) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func lshortfile() string {
|
func lshortfile() string {
|
||||||
return Lshortfile(3)
|
return Lshortfile(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewLogger(out io.Writer, prefix string, flag int, color c.Attribute) (l *Logger) {
|
func NewLogger(out io.Writer, prefix string, flag int, color c.Attribute) (l *Logger) {
|
||||||
|
@ -266,7 +266,6 @@ type extendExpiryDTO struct {
|
|||||||
Days int `json:"days" example:"1"` // Number of days to add.
|
Days int `json:"days" example:"1"` // Number of days to add.
|
||||||
Hours int `json:"hours" example:"2"` // Number of hours to add.
|
Hours int `json:"hours" example:"2"` // Number of hours to add.
|
||||||
Minutes int `json:"minutes" example:"3"` // Number of minutes to add.
|
Minutes int `json:"minutes" example:"3"` // Number of minutes to add.
|
||||||
Timestamp int64 `json:"timestamp"` // Optional, exact time to expire at. Overrides other fields.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type checkUpdateDTO struct {
|
type checkUpdateDTO struct {
|
||||||
|
@ -771,12 +771,6 @@ export class accountsList {
|
|||||||
private _deleteReason = document.getElementById("textarea-delete-user") as HTMLTextAreaElement;
|
private _deleteReason = document.getElementById("textarea-delete-user") as HTMLTextAreaElement;
|
||||||
private _expiryDropdown = document.getElementById("accounts-expiry-dropdown") as HTMLElement;
|
private _expiryDropdown = document.getElementById("accounts-expiry-dropdown") as HTMLElement;
|
||||||
private _extendExpiry = document.getElementById("accounts-extend-expiry") as HTMLSpanElement;
|
private _extendExpiry = document.getElementById("accounts-extend-expiry") as HTMLSpanElement;
|
||||||
private _extendExpiryForm = document.getElementById("form-extend-expiry") as HTMLFormElement;
|
|
||||||
private _extendExpiryTextInput = document.getElementById("extend-expiry-text") as HTMLInputElement;
|
|
||||||
private _extendExpiryFieldInputs = document.getElementById("extend-expiry-field-inputs") as HTMLElement;
|
|
||||||
private _usingExtendExpiryTextInput = true;
|
|
||||||
|
|
||||||
private _extendExpiryDate = document.getElementById("extend-expiry-date") as HTMLElement;
|
|
||||||
private _removeExpiry = document.getElementById("accounts-remove-expiry") as HTMLSpanElement;
|
private _removeExpiry = document.getElementById("accounts-remove-expiry") as HTMLSpanElement;
|
||||||
private _enableExpiryNotify = document.getElementById("expiry-extend-enable") as HTMLInputElement;
|
private _enableExpiryNotify = document.getElementById("expiry-extend-enable") as HTMLInputElement;
|
||||||
private _enableExpiryReason = document.getElementById("textarea-extend-enable") as HTMLTextAreaElement;
|
private _enableExpiryReason = document.getElementById("textarea-extend-enable") as HTMLTextAreaElement;
|
||||||
@ -1631,45 +1625,6 @@ export class accountsList {
|
|||||||
this.reload();
|
this.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
_displayExpiryDate = () => {
|
|
||||||
let date: Date;
|
|
||||||
let invalid = false;
|
|
||||||
if (this._usingExtendExpiryTextInput) {
|
|
||||||
date = (Date as any).fromString(this._extendExpiryTextInput.value) as Date;
|
|
||||||
invalid = "invalid" in (date as any);
|
|
||||||
} else {
|
|
||||||
let fields: Array<HTMLSelectElement> = [
|
|
||||||
document.getElementById("extend-expiry-months") as HTMLSelectElement,
|
|
||||||
document.getElementById("extend-expiry-days") as HTMLSelectElement,
|
|
||||||
document.getElementById("extend-expiry-hours") as HTMLSelectElement,
|
|
||||||
document.getElementById("extend-expiry-minutes") as HTMLSelectElement
|
|
||||||
];
|
|
||||||
invalid = fields[0].value == "0" && fields[1].value == "0" && fields[2].value == "0" && fields[3].value == "0";
|
|
||||||
let id = this._collectUsers().length == 1 ? this._collectUsers()[0] : "";
|
|
||||||
if (!id) invalid = true;
|
|
||||||
else {
|
|
||||||
date = new Date(this._users[id].expiry*1000);
|
|
||||||
if (this._users[id].expiry == 0) date = new Date();
|
|
||||||
date.setMonth(date.getMonth() + (+fields[0].value))
|
|
||||||
date.setDate(date.getDate() + (+fields[1].value));
|
|
||||||
date.setHours(date.getHours() + (+fields[2].value));
|
|
||||||
date.setMinutes(date.getMinutes() + (+fields[3].value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const submit = this._extendExpiryForm.querySelector(`input[type="submit"]`) as HTMLInputElement;
|
|
||||||
const submitSpan = submit.nextElementSibling;
|
|
||||||
if (invalid) {
|
|
||||||
submit.disabled = true;
|
|
||||||
submitSpan.classList.add("opacity-60");
|
|
||||||
this._extendExpiryDate.classList.add("unfocused");
|
|
||||||
} else {
|
|
||||||
submit.disabled = false;
|
|
||||||
submitSpan.classList.remove("opacity-60");
|
|
||||||
this._extendExpiryDate.textContent = window.lang.strings("accountWillExpire").replace("{date}", toDateString(date));
|
|
||||||
this._extendExpiryDate.classList.remove("unfocused");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extendExpiry = (enableUser?: boolean) => {
|
extendExpiry = (enableUser?: boolean) => {
|
||||||
const list = this._collectUsers();
|
const list = this._collectUsers();
|
||||||
let applyList: string[] = [];
|
let applyList: string[] = [];
|
||||||
@ -1692,20 +1647,10 @@ export class accountsList {
|
|||||||
}
|
}
|
||||||
document.getElementById("header-extend-expiry").textContent = header;
|
document.getElementById("header-extend-expiry").textContent = header;
|
||||||
const extend = () => {
|
const extend = () => {
|
||||||
let send = { "users": applyList, "timestamp": 0 }
|
let send = { "users": applyList }
|
||||||
if (this._usingExtendExpiryTextInput) {
|
|
||||||
let date = (Date as any).fromString(this._extendExpiryTextInput.value) as Date;
|
|
||||||
send["timestamp"] = Math.floor(date.getTime() / 1000);
|
|
||||||
if ("invalid" in (date as any)) {
|
|
||||||
window.notifications.customError("extendExpiryError", window.lang.notif("errorInvalidDate"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (let field of ["months", "days", "hours", "minutes"]) {
|
for (let field of ["months", "days", "hours", "minutes"]) {
|
||||||
send[field] = +(document.getElementById("extend-expiry-"+field) as HTMLSelectElement).value;
|
send[field] = +(document.getElementById("extend-expiry-"+field) as HTMLSelectElement).value;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
_post("/users/extend", send, (req: XMLHttpRequest) => {
|
_post("/users/extend", send, (req: XMLHttpRequest) => {
|
||||||
if (req.readyState == 4) {
|
if (req.readyState == 4) {
|
||||||
if (req.status != 200 && req.status != 204) {
|
if (req.status != 200 && req.status != 204) {
|
||||||
@ -1718,7 +1663,8 @@ export class accountsList {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
this._extendExpiryForm.onsubmit = (event: Event) => {
|
const form = document.getElementById("form-extend-expiry") as HTMLFormElement;
|
||||||
|
form.onsubmit = (event: Event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
if (enableUser) {
|
if (enableUser) {
|
||||||
this._enableDisableUsers(applyList, true, this._enableExpiryNotify.checked, this._enableExpiryNotify ? this._enableExpiryReason.value : null, (req: XMLHttpRequest) => {
|
this._enableDisableUsers(applyList, true, this._enableExpiryNotify.checked, this._enableExpiryNotify ? this._enableExpiryReason.value : null, (req: XMLHttpRequest) => {
|
||||||
@ -1739,7 +1685,6 @@ export class accountsList {
|
|||||||
extend();
|
extend();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this._extendExpiryTextInput.value = "";
|
|
||||||
window.modals.extendExpiry.show();
|
window.modals.extendExpiry.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1876,37 +1821,6 @@ export class accountsList {
|
|||||||
this._extendExpiry.onclick = () => { this.extendExpiry(); };
|
this._extendExpiry.onclick = () => { this.extendExpiry(); };
|
||||||
this._removeExpiry.onclick = () => { this.removeExpiry(); };
|
this._removeExpiry.onclick = () => { this.removeExpiry(); };
|
||||||
this._expiryDropdown.classList.add("unfocused");
|
this._expiryDropdown.classList.add("unfocused");
|
||||||
this._extendExpiryDate.classList.add("unfocused");
|
|
||||||
|
|
||||||
this._extendExpiryTextInput.onkeyup = () => {
|
|
||||||
this._extendExpiryTextInput.parentElement.parentElement.classList.remove("opacity-60");
|
|
||||||
this._extendExpiryFieldInputs.classList.add("opacity-60");
|
|
||||||
this._usingExtendExpiryTextInput = true;
|
|
||||||
this._displayExpiryDate();
|
|
||||||
}
|
|
||||||
|
|
||||||
this._extendExpiryTextInput.onclick = () => {
|
|
||||||
this._extendExpiryTextInput.parentElement.parentElement.classList.remove("opacity-60");
|
|
||||||
this._extendExpiryFieldInputs.classList.add("opacity-60");
|
|
||||||
this._usingExtendExpiryTextInput = true;
|
|
||||||
this._displayExpiryDate();
|
|
||||||
};
|
|
||||||
|
|
||||||
this._extendExpiryFieldInputs.onclick = () => {
|
|
||||||
this._extendExpiryFieldInputs.classList.remove("opacity-60");
|
|
||||||
this._extendExpiryTextInput.parentElement.parentElement.classList.add("opacity-60");
|
|
||||||
this._usingExtendExpiryTextInput = false;
|
|
||||||
this._displayExpiryDate();
|
|
||||||
};
|
|
||||||
|
|
||||||
for (let field of ["months", "days", "hours", "minutes"]) {
|
|
||||||
(document.getElementById("extend-expiry-"+field) as HTMLSelectElement).onchange = () => {
|
|
||||||
this._extendExpiryFieldInputs.classList.remove("opacity-60");
|
|
||||||
this._extendExpiryTextInput.parentElement.parentElement.classList.add("opacity-60");
|
|
||||||
this._usingExtendExpiryTextInput = false;
|
|
||||||
this._displayExpiryDate();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
this._disableEnable.onclick = this.enableDisableUsers;
|
this._disableEnable.onclick = this.enableDisableUsers;
|
||||||
this._disableEnable.parentElement.classList.add("unfocused");
|
this._disableEnable.parentElement.classList.add("unfocused");
|
||||||
|
@ -161,7 +161,6 @@ func newUpdater(buildroneURL, namespace, repo, version, commit, buildType string
|
|||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
binary += ".exe"
|
binary += ".exe"
|
||||||
}
|
}
|
||||||
fmt.Println("monitoring", tag)
|
|
||||||
return &Updater{
|
return &Updater{
|
||||||
httpClient: &http.Client{Timeout: 10 * time.Second},
|
httpClient: &http.Client{Timeout: 10 * time.Second},
|
||||||
timeoutHandler: common.NewTimeoutHandler("updater", buildroneURL, true),
|
timeoutHandler: common.NewTimeoutHandler("updater", buildroneURL, true),
|
||||||
@ -212,7 +211,7 @@ func (ud *Updater) GetTag() (Tag, int, error) {
|
|||||||
var tag Tag
|
var tag Tag
|
||||||
err = json.Unmarshal(body, &tag)
|
err = json.Unmarshal(body, &tag)
|
||||||
if tag.Version == "" {
|
if tag.Version == "" {
|
||||||
err = errors.New("Tag at \"" + url + "\" was empty")
|
err = errors.New("Tag was empty")
|
||||||
}
|
}
|
||||||
return tag, resp.StatusCode, err
|
return tag, resp.StatusCode, err
|
||||||
}
|
}
|
||||||
|
10
views.go
10
views.go
@ -234,11 +234,6 @@ func (app *appContext) MyUserPage(gc *gin.Context) {
|
|||||||
data["discordServerName"] = app.discord.serverName
|
data["discordServerName"] = app.discord.serverName
|
||||||
data["discordInviteLink"] = app.discord.inviteChannelName != ""
|
data["discordInviteLink"] = app.discord.inviteChannelName != ""
|
||||||
}
|
}
|
||||||
if data["linkResetEnabled"].(bool) {
|
|
||||||
data["resetPasswordUsername"] = app.config.Section("user_page").Key("allow_pwr_username").MustBool(true)
|
|
||||||
data["resetPasswordEmail"] = app.config.Section("user_page").Key("allow_pwr_email").MustBool(true)
|
|
||||||
data["resetPasswordContactMethod"] = app.config.Section("user_page").Key("allow_pwr_contact_method").MustBool(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
pageMessagesExist := map[string]bool{}
|
pageMessagesExist := map[string]bool{}
|
||||||
pageMessages := map[string]CustomContent{}
|
pageMessages := map[string]CustomContent{}
|
||||||
@ -280,8 +275,7 @@ func (app *appContext) ResetPassword(gc *gin.Context) {
|
|||||||
"ombiEnabled": app.config.Section("ombi").Key("enabled").MustBool(false),
|
"ombiEnabled": app.config.Section("ombi").Key("enabled").MustBool(false),
|
||||||
}
|
}
|
||||||
pwr, isInternal := app.internalPWRs[pin]
|
pwr, isInternal := app.internalPWRs[pin]
|
||||||
// if isInternal && setPassword {
|
if isInternal && setPassword {
|
||||||
if setPassword {
|
|
||||||
data["helpMessage"] = app.config.Section("ui").Key("help_message").String()
|
data["helpMessage"] = app.config.Section("ui").Key("help_message").String()
|
||||||
data["successMessage"] = app.config.Section("ui").Key("success_message").String()
|
data["successMessage"] = app.config.Section("ui").Key("success_message").String()
|
||||||
data["jfLink"] = app.config.Section("ui").Key("redirect_url").String()
|
data["jfLink"] = app.config.Section("ui").Key("redirect_url").String()
|
||||||
@ -325,7 +319,7 @@ func (app *appContext) ResetPassword(gc *gin.Context) {
|
|||||||
var status int
|
var status int
|
||||||
var err error
|
var err error
|
||||||
var username string
|
var username string
|
||||||
if !isInternal && !setPassword {
|
if !isInternal {
|
||||||
resp, status, err = app.jf.ResetPassword(pin)
|
resp, status, err = app.jf.ResetPassword(pin)
|
||||||
} else if time.Now().After(pwr.Expiry) {
|
} else if time.Now().After(pwr.Expiry) {
|
||||||
app.debug.Printf("Ignoring PWR request due to expired internal PIN: %s", pin)
|
app.debug.Printf("Ignoring PWR request due to expired internal PIN: %s", pin)
|
||||||
|
Loading…
Reference in New Issue
Block a user