mirror of
https://github.com/hrfee/jfa-go.git
synced 2024-12-22 09:00:10 +00:00
config: migrate "url_base" dupes to "jfa_url"
URL Base now refers to JUST the subfolder portion, i.e. `/accounts` if you access jfa-go at `http://jellyf.in/accounts`. General > "jfa_url"/"External jfa-go URL" now refers to the WHOLE URL you access jfa-go at, i.e. `http://jellyf.in/accounts`. The settings in "invite emails" and "password resets" have been removed, and a value chosen from the two applied to "jfa_url". Migration also makes a config backup. Adds a "deprecated" flag to config-base, which just tells the UI to not show it (for now). Also added some warnings related to the URL base / External URL.
This commit is contained in:
parent
0e7245e6b9
commit
e71d492495
9
api.go
9
api.go
@ -322,15 +322,6 @@ func (app *appContext) GetConfig(gc *gin.Context) {
|
||||
resp.Sections["discord"].Settings["language"] = tl
|
||||
resp.Sections["matrix"].Settings["language"] = tl
|
||||
|
||||
// if setting := resp.Sections["invite_emails"].Settings["url_base"]; setting.Value == "" {
|
||||
// setting.Value = strings.TrimSuffix(resp.Sections["password_resets"].Settings["url_base"].Value.(string), "/invite")
|
||||
// resp.Sections["invite_emails"].Settings["url_base"] = setting
|
||||
// }
|
||||
// if setting := resp.Sections["password_resets"].Settings["url_base"]; setting.Value == "" {
|
||||
// setting.Value = strings.TrimSuffix(resp.Sections["invite_emails"].Settings["url_base"].Value.(string), "/invite")
|
||||
// resp.Sections["password_resets"].Settings["url_base"] = setting
|
||||
// }
|
||||
|
||||
gc.JSON(200, resp)
|
||||
}
|
||||
|
||||
|
15
config.go
15
config.go
@ -55,7 +55,16 @@ func (app *appContext) loadConfig() error {
|
||||
for _, key := range []string{"matrix_sql"} {
|
||||
app.config.Section("files").Key(key).SetValue(app.config.Section("files").Key(key).MustString(filepath.Join(app.dataPath, (key + ".db"))))
|
||||
}
|
||||
|
||||
app.URLBase = strings.TrimSuffix(app.config.Section("ui").Key("url_base").MustString(""), "/")
|
||||
if app.URLBase == "/invite" || app.URLBase == "/accounts" || app.URLBase == "/settings" || app.URLBase == "/activity" {
|
||||
app.err.Printf(lm.BadURLBase, app.URLBase)
|
||||
}
|
||||
app.ExternalHost = strings.TrimSuffix(strings.TrimSuffix(app.config.Section("ui").Key("jfa_url").MustString(""), "/invite"), "/")
|
||||
if !strings.HasSuffix(app.ExternalHost, app.URLBase) {
|
||||
app.err.Println(lm.NoURLSuffix)
|
||||
}
|
||||
|
||||
app.config.Section("email").Key("no_username").SetValue(strconv.FormatBool(app.config.Section("email").Key("no_username").MustBool(false)))
|
||||
|
||||
app.MustSetValue("password_resets", "email_html", "jfa-go:"+"email.html")
|
||||
@ -128,12 +137,6 @@ func (app *appContext) loadConfig() error {
|
||||
LOGIP = app.config.Section("advanced").Key("log_ips").MustBool(false)
|
||||
LOGIPU = app.config.Section("advanced").Key("log_ips_users").MustBool(false)
|
||||
|
||||
// These two settings are pretty much the same
|
||||
url1 := app.config.Section("invite_emails").Key("url_base").String()
|
||||
url2 := app.config.Section("password_resets").Key("url_base").String()
|
||||
app.MustSetValue("password_resets", "url_base", strings.TrimSuffix(url1, "/invite"))
|
||||
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 {
|
||||
|
@ -257,6 +257,15 @@
|
||||
"value": "",
|
||||
"description": "URL base for when running jfa-go with a reverse proxy in a subfolder. include preceding /, e.g \"/accounts\"."
|
||||
},
|
||||
"jfa_url": {
|
||||
"name": "External jfa-go URL",
|
||||
"required": true,
|
||||
"requires_restart": false,
|
||||
"depends_true": "enabled",
|
||||
"type": "text",
|
||||
"value": "http://accounts.jellyf.in:8056",
|
||||
"description": "The URL at which the jfa-go root (admin page) is accessible, including the subfolder if you use one. This is necessary because using a reverse proxy means the program has no way of knowing the URL itself."
|
||||
},
|
||||
"redirect_url": {
|
||||
"name": "Form success redirect URL",
|
||||
"required": false,
|
||||
@ -1375,13 +1384,22 @@
|
||||
"description": "Instead of automatically setting the user's password to the PIN, allow them to set a new password through the reset link."
|
||||
},
|
||||
"url_base": {
|
||||
"name": "URL Base",
|
||||
"name": "External jfa-go URL",
|
||||
"required": true,
|
||||
"requires_restart": false,
|
||||
"depends_true": "link_reset",
|
||||
"type": "text",
|
||||
"value": "http://accounts.jellyf.in:8056",
|
||||
"description": "Base URL for jfa-go. You can leave this if you have one set in \"Invite Emails\". This is necessary because using a reverse proxy means the program has no way of knowing the URL itself."
|
||||
"description": "The URL at which the jfa-go admin page is accessible, including the subfolder if you use one. You can leave this if you have one set in \"Invite Emails\". This is necessary because using a reverse proxy means the program has no way of knowing the URL itself.",
|
||||
"deprecated": true
|
||||
},
|
||||
"jfa_url": {
|
||||
"name": "Generating Reset Links:",
|
||||
"type": "note",
|
||||
"value": "",
|
||||
"depends_true": "link_reset",
|
||||
"required": "false",
|
||||
"description": "Set the \"External jfa-go URL\" in General so that links to jfa-go can be made."
|
||||
},
|
||||
"language": {
|
||||
"name": "Default reset link language",
|
||||
@ -1471,13 +1489,22 @@
|
||||
"description": "Subject of invite emails."
|
||||
},
|
||||
"url_base": {
|
||||
"name": "URL Base",
|
||||
"name": "External jfa-go URL",
|
||||
"required": true,
|
||||
"requires_restart": false,
|
||||
"depends_true": "enabled",
|
||||
"type": "text",
|
||||
"value": "http://accounts.jellyf.in:8056",
|
||||
"description": "Base URL for jfa-go. This is necessary because using a reverse proxy means the program has no way of knowing the URL itself."
|
||||
"description": "The URL at which the jfa-go root (admin page) is accessible, including the subfolder if you use one. You can leave this if you have one set in \"Invite Emails\". This is necessary because using a reverse proxy means the program has no way of knowing the URL itself.",
|
||||
"deprecated": true
|
||||
},
|
||||
"jfa_url": {
|
||||
"name": "Generating Links:",
|
||||
"type": "note",
|
||||
"value": "",
|
||||
"depends_true": "enabled",
|
||||
"required": "false",
|
||||
"description": "Set the \"External jfa-go URL\" in General so that links to jfa-go can be made."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
16
email.go
16
email.go
@ -325,17 +325,11 @@ func (emailer *Emailer) confirmationValues(code, username, key string, app *appC
|
||||
}
|
||||
} else {
|
||||
message := app.config.Section("messages").Key("message").String()
|
||||
inviteLink := app.config.Section("invite_emails").Key("url_base").String()
|
||||
inviteLink := app.ExternalHost
|
||||
if code == "" { // Personal email change
|
||||
if strings.HasSuffix(inviteLink, "/invite") {
|
||||
inviteLink = strings.TrimSuffix(inviteLink, "/invite")
|
||||
}
|
||||
inviteLink = fmt.Sprintf("%s/my/confirm/%s", inviteLink, url.PathEscape(key))
|
||||
} else { // Invite email confirmation
|
||||
if !strings.HasSuffix(inviteLink, "/invite") {
|
||||
inviteLink += "/invite"
|
||||
}
|
||||
inviteLink = fmt.Sprintf("%s/%s?key=%s", inviteLink, code, url.PathEscape(key))
|
||||
inviteLink = fmt.Sprintf("%s/invite/%s?key=%s", inviteLink, code, url.PathEscape(key))
|
||||
}
|
||||
template["helloUser"] = emailer.lang.Strings.template("helloUser", tmpl{"username": username})
|
||||
template["confirmationURL"] = inviteLink
|
||||
@ -399,11 +393,7 @@ func (emailer *Emailer) inviteValues(code string, invite Invite, app *appContext
|
||||
expiry := invite.ValidTill
|
||||
d, t, expiresIn := emailer.formatExpiry(expiry, false, app.datePattern, app.timePattern)
|
||||
message := app.config.Section("messages").Key("message").String()
|
||||
inviteLink := app.config.Section("invite_emails").Key("url_base").String()
|
||||
if !strings.HasSuffix(inviteLink, "/invite") {
|
||||
inviteLink += "/invite"
|
||||
}
|
||||
inviteLink = fmt.Sprintf("%s/%s", inviteLink, code)
|
||||
inviteLink := fmt.Sprintf("%s/invite/%s", app.ExternalHost, code)
|
||||
template := map[string]interface{}{
|
||||
"hello": emailer.lang.InviteEmail.get("hello"),
|
||||
"youHaveBeenInvited": emailer.lang.InviteEmail.get("youHaveBeenInvited"),
|
||||
|
@ -110,9 +110,14 @@
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-4">{{ .lang.General.urlBase }} ({{ .lang.Strings.optional }})</span>
|
||||
<input type="url" class="input ~neutral @low mt-4" id="ui-url_base">
|
||||
<input type="text" class="input ~neutral @low mt-4" id="ui-url_base" placeholder="/mysubfolder">
|
||||
<p class="support mb-2 mt-1">{{ .lang.General.urlBaseNotice }}</p>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-4">{{ .lang.General.externalURL }}</span>
|
||||
<input type="text" class="input ~neutral @low mt-4" id="ui-jfa_url" placeholder="https://jellyf.in/mysubfolder">
|
||||
<p class="support mb-2 mt-1">{{ .lang.General.externalURLNotice }}</p>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span>{{ .lang.Strings.theme }}</span>
|
||||
<div class="select ~neutral @low mt-4 mb-2">
|
||||
@ -423,10 +428,6 @@
|
||||
<label class="row switch pb-4">
|
||||
<input type="checkbox" class="mr-2" id="invite_emails-enabled"><span>{{ .lang.Strings.enabled }}</span>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-4">{{ .lang.Strings.URL }}</span>
|
||||
<input type="url" class="input ~neutral @low mt-4 mb-2" id="invite_emails-url_base" placeholder="https://accounts.jellyf.in/invite">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-4">{{ .lang.Strings.emailSubject }}</span>
|
||||
<input type="text" class="input ~neutral @low mt-4 mb-2" id="invite_emails-subject" placeholder="{{ .emailLang.InviteEmail.title }}">
|
||||
|
@ -48,6 +48,8 @@
|
||||
"listenAddress": "Listen Address",
|
||||
"urlBase": "URL Base",
|
||||
"urlBaseNotice": "Only needed if using a reverse proxy on a subfolder (e.g 'jellyf.in/accounts').",
|
||||
"externalURL": "External jfa-go URL",
|
||||
"externalURLNotice": "The URL you'll be accessing jfa-go from. Used to generate links for things like password resets. Make sure to include the above URL base if you set one.",
|
||||
"lightTheme": "Light",
|
||||
"darkTheme": "Dark",
|
||||
"useHTTPS": "Use HTTPS",
|
||||
|
@ -207,6 +207,9 @@ const (
|
||||
EnableAllPWRMethods = "No PWR method preferences set in [user_page], all will be enabled"
|
||||
InitProxy = "Initialized proxy @ \"%s\""
|
||||
FailedInitProxy = "Failed to initialize proxy @ \"%s\": %v\nStartup will pause for a bit to grab your attention."
|
||||
NoURLSuffix = `Warning: Given "jfa_url"/"External jfa-go URL" value does not include "url_base" value!`
|
||||
BadURLBase = `Warning: Given URL Base "%s" may conflict with the applications subpaths.`
|
||||
NoExternalHost = `No "External jfa-go URL" provided, set one in Settings > General.`
|
||||
|
||||
// discord.go
|
||||
StartDaemon = "Started %s daemon"
|
||||
|
60
main.go
60
main.go
@ -101,36 +101,36 @@ type appContext struct {
|
||||
adminUsers []User
|
||||
invalidTokens []string
|
||||
// Keeping jf name because I can't think of a better one
|
||||
jf *mediabrowser.MediaBrowser
|
||||
authJf *mediabrowser.MediaBrowser
|
||||
ombi *OmbiWrapper
|
||||
js *JellyseerrWrapper
|
||||
thirdPartyServices []ThirdPartyService
|
||||
datePattern string
|
||||
timePattern string
|
||||
storage Storage
|
||||
validator Validator
|
||||
email *Emailer
|
||||
telegram *TelegramDaemon
|
||||
discord *DiscordDaemon
|
||||
matrix *MatrixDaemon
|
||||
contactMethods []ContactMethodLinker
|
||||
info, debug, err *logger.Logger
|
||||
host string
|
||||
port int
|
||||
version string
|
||||
URLBase string
|
||||
updater *Updater
|
||||
newUpdate bool // Whether whatever's in update is new.
|
||||
tag Tag
|
||||
update Update
|
||||
proxyEnabled bool
|
||||
proxyTransport *http.Transport
|
||||
proxyConfig easyproxy.ProxyConfig
|
||||
internalPWRs map[string]InternalPWR
|
||||
pwrCaptchas map[string]Captcha
|
||||
ConfirmationKeys map[string]map[string]newUserDTO // Map of invite code to jwt to request
|
||||
confirmationKeysLock sync.Mutex
|
||||
jf *mediabrowser.MediaBrowser
|
||||
authJf *mediabrowser.MediaBrowser
|
||||
ombi *OmbiWrapper
|
||||
js *JellyseerrWrapper
|
||||
thirdPartyServices []ThirdPartyService
|
||||
datePattern string
|
||||
timePattern string
|
||||
storage Storage
|
||||
validator Validator
|
||||
email *Emailer
|
||||
telegram *TelegramDaemon
|
||||
discord *DiscordDaemon
|
||||
matrix *MatrixDaemon
|
||||
contactMethods []ContactMethodLinker
|
||||
info, debug, err *logger.Logger
|
||||
host string
|
||||
port int
|
||||
version string
|
||||
URLBase, ExternalHost string
|
||||
updater *Updater
|
||||
newUpdate bool // Whether whatever's in update is new.
|
||||
tag Tag
|
||||
update Update
|
||||
proxyEnabled bool
|
||||
proxyTransport *http.Transport
|
||||
proxyConfig easyproxy.ProxyConfig
|
||||
internalPWRs map[string]InternalPWR
|
||||
pwrCaptchas map[string]Captcha
|
||||
ConfirmationKeys map[string]map[string]newUserDTO // Map of invite code to jwt to request
|
||||
confirmationKeysLock sync.Mutex
|
||||
}
|
||||
|
||||
func generateSecret(length int) (string, error) {
|
||||
|
@ -14,6 +14,7 @@ import (
|
||||
func runMigrations(app *appContext) {
|
||||
migrateProfiles(app)
|
||||
migrateBootstrap(app)
|
||||
migrateExternalURL(app)
|
||||
migrateEmailStorage(app)
|
||||
migrateNotificationMethods(app)
|
||||
linkExistingOmbiDiscordTelegram(app)
|
||||
@ -463,3 +464,37 @@ func intialiseCustomContent(app *appContext) {
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// Migrate poorly-named and duplicate "url_base" settings to the single "external jfa-go URL" setting.
|
||||
func migrateExternalURL(app *appContext) {
|
||||
tempConfig, _ := ini.Load(app.configPath)
|
||||
err := tempConfig.SaveTo(app.configPath + "_" + commit + ".bak")
|
||||
if err != nil {
|
||||
app.err.Fatalf("Failed to backup config: %v", err)
|
||||
return
|
||||
}
|
||||
url1 := app.config.Section("password_resets").Key("url_base").String()
|
||||
url2 := app.config.Section("invite_emails").Key("url_base").String()
|
||||
if tempConfig.Section("ui").Key("jfa_url").String() != "" || (url1 == "" && url2 == "") {
|
||||
return
|
||||
}
|
||||
|
||||
preferred := url1
|
||||
// the PWR setting (url1) is preferred, as it has always been defined as the URL root, while
|
||||
// the invite email setting (url2) once asked for "/invite" at the end.
|
||||
if url1 == "" {
|
||||
preferred = strings.TrimSuffix(url2, "/invite")
|
||||
}
|
||||
|
||||
fmt.Println(warning("The duplicate URL Base settings in \"Invite emails\" and \"Password Resets\" have been merged into General > External jfa-go URL. A backup config has been made."))
|
||||
|
||||
tempConfig.Section("ui").Key("jfa_url").SetValue(preferred)
|
||||
app.config.Section("password_resets").DeleteKey("url_base")
|
||||
app.config.Section("invite_emails").DeleteKey("url_base")
|
||||
|
||||
err = tempConfig.SaveTo(app.configPath)
|
||||
if err != nil {
|
||||
app.err.Fatalf("Failed to save new config: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -229,6 +229,7 @@ type setting struct {
|
||||
DependsTrue string `json:"depends_true,omitempty"` // If specified, this field is enabled when the specified bool setting is enabled.
|
||||
DependsFalse string `json:"depends_false,omitempty"` // If specified, opposite behaviour of DependsTrue.
|
||||
Style string `json:"style,omitempty"`
|
||||
Deprecated bool `json:"deprecated,omitempty"`
|
||||
}
|
||||
|
||||
type section struct {
|
||||
|
@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
@ -29,10 +30,10 @@ func (app *appContext) GenInternalReset(userID string) (InternalPWR, error) {
|
||||
|
||||
// GenResetLink generates and returns a password reset link.
|
||||
func (app *appContext) GenResetLink(pin string) (string, error) {
|
||||
url := app.config.Section("password_resets").Key("url_base").String()
|
||||
url := app.ExternalHost
|
||||
var pinLink string
|
||||
if url == "" {
|
||||
return pinLink, fmt.Errorf("disabled as no URL Base provided. Set in Settings > Password Resets.")
|
||||
return pinLink, errors.New(lm.NoExternalHost)
|
||||
}
|
||||
// Strip /invite from end of this URL, ik it's ugly.
|
||||
pinLink = fmt.Sprintf("%s/reset?pin=%s", url, pin)
|
||||
|
@ -33,6 +33,7 @@ interface Setting {
|
||||
depends_true?: string;
|
||||
depends_false?: string;
|
||||
wiki_link?: string;
|
||||
deprecated?: boolean;
|
||||
|
||||
asElement: () => HTMLElement;
|
||||
update: (s: Setting) => void;
|
||||
@ -579,6 +580,7 @@ class sectionPanel {
|
||||
if (name in this._settings) {
|
||||
this._settings[name].update(setting);
|
||||
} else {
|
||||
if (setting.deprecated) continue;
|
||||
switch (setting.type) {
|
||||
case "text":
|
||||
setting = new DOMText(setting, this._sectionName, name);
|
||||
|
@ -249,6 +249,7 @@ const settings = {
|
||||
"host": new Input(get("ui-host")),
|
||||
"port": new Input(get("ui-port")),
|
||||
"url_base": new Input(get("ui-url_base")),
|
||||
"jfa_url": new Input(get("ui-jfa_url")),
|
||||
"theme": new Select(get("ui-theme")),
|
||||
"language-form": new LangSelect("form", get("ui-language-form")),
|
||||
"language-admin": new LangSelect("admin", get("ui-language-admin")),
|
||||
@ -304,7 +305,6 @@ const settings = {
|
||||
"invite_emails": {
|
||||
"enabled": new Checkbox(get("invite_emails-enabled"), "", false, "invite_emails", "enabled"),
|
||||
"subject": new Input(get("invite_emails-subject"), "", "", "enabled", true, "invite_emails"),
|
||||
"url_base": new Input(get("invite_emails-url_base"), "", "", "enabled", true, "invite_emails")
|
||||
},
|
||||
"mailgun": {
|
||||
"api_url": new Input(get("mailgun-api_url")),
|
||||
|
6
views.go
6
views.go
@ -740,11 +740,7 @@ func (app *appContext) InviteProxy(gc *gin.Context) {
|
||||
discord := discordEnabled && app.config.Section("discord").Key("show_on_reg").MustBool(true)
|
||||
matrix := matrixEnabled && app.config.Section("matrix").Key("show_on_reg").MustBool(true)
|
||||
|
||||
userPageAddress := app.config.Section("invite_emails").Key("url_base").String()
|
||||
if userPageAddress == "" {
|
||||
userPageAddress = app.config.Section("password_resets").Key("url_base").String()
|
||||
}
|
||||
userPageAddress += "/my/account"
|
||||
userPageAddress := fmt.Sprintf("%s/my/account", app.ExternalHost)
|
||||
|
||||
fromUser := ""
|
||||
if invite.ReferrerJellyfinID != "" {
|
||||
|
Loading…
Reference in New Issue
Block a user