mirror of
https://github.com/hrfee/jfa-go.git
synced 2024-12-22 00:50:12 +00:00
form/admin: don't allow "+" in username/email
Jellyfin doesn't like this.
This commit is contained in:
parent
a7aa3fd53e
commit
6c30a1ff40
2
Makefile
2
Makefile
@ -196,7 +196,7 @@ STATIC_TARGET = $(STATIC_SRC:static/%=$(DATA)/web/%)
|
|||||||
COPY_SRC = images/banner.svg jfa-go.service LICENSE $(LANG_SRC) $(STATIC_SRC)
|
COPY_SRC = images/banner.svg jfa-go.service LICENSE $(LANG_SRC) $(STATIC_SRC)
|
||||||
COPY_TARGET = $(DATA)/jfa-go.service
|
COPY_TARGET = $(DATA)/jfa-go.service
|
||||||
# $(DATA)/LICENSE $(LANG_TARGET) $(STATIC_TARGET) $(DATA)/web/css/$(CSSVERSION)bundle.css
|
# $(DATA)/LICENSE $(LANG_TARGET) $(STATIC_TARGET) $(DATA)/web/css/$(CSSVERSION)bundle.css
|
||||||
$(COPY_TARGET): $(INLINE_TARGET) $(STATIC_SRC)
|
$(COPY_TARGET): $(INLINE_TARGET) $(STATIC_SRC) $(LANG_SRC)
|
||||||
$(info copying crash page)
|
$(info copying crash page)
|
||||||
cp $(DATA)/crash.html $(DATA)/html/
|
cp $(DATA)/crash.html $(DATA)/html/
|
||||||
$(info copying static data)
|
$(info copying static data)
|
||||||
|
@ -48,7 +48,8 @@
|
|||||||
"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."
|
"errorSaveSettings": "Couldn't save settings.",
|
||||||
|
"errorSpecialSymbols": "Field cannot contain special symbols."
|
||||||
},
|
},
|
||||||
"quantityStrings": {
|
"quantityStrings": {
|
||||||
"year": {
|
"year": {
|
||||||
@ -64,4 +65,4 @@
|
|||||||
"plural": "{n} Days"
|
"plural": "{n} Days"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,14 @@ func lshortfile() string {
|
|||||||
return Lshortfile(3)
|
return Lshortfile(3)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func LshortfileTree() string {
|
||||||
|
out := ""
|
||||||
|
for i := 6; i >= 0; i-- {
|
||||||
|
out += strconv.Itoa(i) + ":" + Lshortfile(i) + " "
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
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) {
|
||||||
l = &Logger{}
|
l = &Logger{}
|
||||||
// Use reimplemented Lshortfile since wrapping the log functions messes them up
|
// Use reimplemented Lshortfile since wrapping the log functions messes them up
|
||||||
@ -96,6 +104,13 @@ func (l *Logger) PrintfCustomLevel(level int, format string, v ...interface{}) {
|
|||||||
l.logger.Print(out)
|
l.logger.Print(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *Logger) PrintfNoFile(format string, v ...interface{}) {
|
||||||
|
if l.empty {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
l.logger.Print(l.printer.Sprintf(format, v...))
|
||||||
|
}
|
||||||
|
|
||||||
func (l *Logger) Print(v ...interface{}) {
|
func (l *Logger) Print(v ...interface{}) {
|
||||||
if l.empty {
|
if l.empty {
|
||||||
return
|
return
|
||||||
|
@ -175,6 +175,7 @@ const (
|
|||||||
AccountLinked = "account already linked and require_unique enabled"
|
AccountLinked = "account already linked and require_unique enabled"
|
||||||
AccountUnverified = "unverified"
|
AccountUnverified = "unverified"
|
||||||
FailedSetDiscordMemberRole = "Failed to apply/remove " + Discord + " member role: %v"
|
FailedSetDiscordMemberRole = "Failed to apply/remove " + Discord + " member role: %v"
|
||||||
|
InvalidChar = "Invalid character '%c'"
|
||||||
|
|
||||||
FailedSetEmailAddress = "Failed to set email address for %s user \"%s\": %v"
|
FailedSetEmailAddress = "Failed to set email address for %s user \"%s\": %v"
|
||||||
|
|
||||||
|
@ -5,8 +5,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type stringResponse struct {
|
type stringResponse struct {
|
||||||
Response string `json:"response" example:"message"`
|
Response string `json:"response" example:"message"`
|
||||||
Error string `json:"error" example:"errorDescription"`
|
ErrorText string `json:"error" example:"No special symbols allowed."`
|
||||||
|
ErrorCode string `json:"error_code" example:"errorSpecialSymbols"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type boolResponse struct {
|
type boolResponse struct {
|
||||||
|
19
ts/form.ts
19
ts/form.ts
@ -176,13 +176,32 @@ const rePasswordField = document.getElementById("create-reenter-password") as HT
|
|||||||
|
|
||||||
let captcha = new Captcha(window.code, window.captcha, window.reCAPTCHA, false);
|
let captcha = new Captcha(window.code, window.captcha, window.reCAPTCHA, false);
|
||||||
|
|
||||||
|
const clearSubmitButton = () => {
|
||||||
|
submitInput.setCustomValidity("");
|
||||||
|
submitSpan.title = "";
|
||||||
|
};
|
||||||
|
|
||||||
|
const invalidMessage = (el: HTMLInputElement, msg: string) => {
|
||||||
|
el.setCustomValidity(msg);
|
||||||
|
submitInput.setCustomValidity(msg);
|
||||||
|
submitSpan.title = msg;
|
||||||
|
};
|
||||||
|
|
||||||
function _baseValidator(oncomplete: (valid: boolean) => void, captchaValid: boolean): void {
|
function _baseValidator(oncomplete: (valid: boolean) => void, captchaValid: boolean): void {
|
||||||
|
clearSubmitButton();
|
||||||
if (window.emailRequired) {
|
if (window.emailRequired) {
|
||||||
if (!emailField.value.includes("@")) {
|
if (!emailField.value.includes("@")) {
|
||||||
oncomplete(false);
|
oncomplete(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
usernameField.setCustomValidity("");
|
||||||
|
// Jellyfin doesn't like having "+" in the username field
|
||||||
|
if (usernameField.value.includes("+")) {
|
||||||
|
invalidMessage(usernameField, window.messages["errorSpecialSymbols"]);
|
||||||
|
oncomplete(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (window.discordEnabled && window.discordRequired && !discordVerified) {
|
if (window.discordEnabled && window.discordRequired && !discordVerified) {
|
||||||
oncomplete(false);
|
oncomplete(false);
|
||||||
return;
|
return;
|
||||||
|
@ -1138,7 +1138,12 @@ export class accountsList {
|
|||||||
console.log("User created, but welcome email failed");
|
console.log("User created, but welcome email failed");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
window.notifications.customError("addUser", window.lang.var("notifications", "errorUserCreated", `"${send['username']}"`));
|
let msg = window.lang.var("notifications", "errorUserCreated", `"${send['username']}"`);
|
||||||
|
if ("error" in req.response) {
|
||||||
|
let realError = window.lang.notif(req.response["error"]);
|
||||||
|
if (realError) msg = realError;
|
||||||
|
}
|
||||||
|
window.notifications.customError("addUser", msg);
|
||||||
}
|
}
|
||||||
if (req.response["error"] as String) {
|
if (req.response["error"] as String) {
|
||||||
console.log(req.response["error"]);
|
console.log(req.response["error"]);
|
||||||
|
17
users.go
17
users.go
@ -1,10 +1,13 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/hrfee/jfa-go/logger"
|
||||||
lm "github.com/hrfee/jfa-go/logmessages"
|
lm "github.com/hrfee/jfa-go/logmessages"
|
||||||
"github.com/hrfee/mediabrowser"
|
"github.com/hrfee/mediabrowser"
|
||||||
"github.com/lithammer/shortuuid/v3"
|
"github.com/lithammer/shortuuid/v3"
|
||||||
@ -53,9 +56,11 @@ type NewUserData struct {
|
|||||||
func (app *appContext) NewUserPostVerification(p NewUserParams) (out NewUserData, pendingTasks *sync.WaitGroup) {
|
func (app *appContext) NewUserPostVerification(p NewUserParams) (out NewUserData, pendingTasks *sync.WaitGroup) {
|
||||||
pendingTasks = &sync.WaitGroup{}
|
pendingTasks = &sync.WaitGroup{}
|
||||||
// Some helper functions which will behave as our app.info/error/debug
|
// Some helper functions which will behave as our app.info/error/debug
|
||||||
|
// And make sure we capture the correct caller location.
|
||||||
deferLogInfo := func(s string, args ...any) {
|
deferLogInfo := func(s string, args ...any) {
|
||||||
|
loc := logger.Lshortfile(2)
|
||||||
out.Log = func() {
|
out.Log = func() {
|
||||||
app.info.Printf(s, args)
|
app.info.PrintfNoFile(loc+" "+s, args...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* deferLogDebug := func(s string, args ...any) {
|
/* deferLogDebug := func(s string, args ...any) {
|
||||||
@ -64,11 +69,19 @@ func (app *appContext) NewUserPostVerification(p NewUserParams) (out NewUserData
|
|||||||
}
|
}
|
||||||
} */
|
} */
|
||||||
deferLogError := func(s string, args ...any) {
|
deferLogError := func(s string, args ...any) {
|
||||||
|
loc := logger.Lshortfile(2)
|
||||||
out.Log = func() {
|
out.Log = func() {
|
||||||
app.err.Printf(s, args)
|
app.err.PrintfNoFile(loc+" "+s, args...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if strings.ContainsRune(p.Req.Username, '+') {
|
||||||
|
deferLogError(lm.FailedCreateUser, lm.Jellyfin, p.Req.Username, fmt.Sprintf(lm.InvalidChar, '+'))
|
||||||
|
out.Status = 400
|
||||||
|
out.Message = "errorSpecialSymbols"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
existingUser, _ := app.jf.UserByName(p.Req.Username, false)
|
existingUser, _ := app.jf.UserByName(p.Req.Username, false)
|
||||||
if existingUser.Name != "" {
|
if existingUser.Name != "" {
|
||||||
out.Message = lm.UserExists
|
out.Message = lm.UserExists
|
||||||
|
Loading…
Reference in New Issue
Block a user