mirror of
https://github.com/hrfee/jfa-go.git
synced 2024-12-29 12:30:11 +00:00
Compare commits
3 Commits
ebacfd43be
...
8113f794ab
Author | SHA1 | Date | |
---|---|---|---|
8113f794ab | |||
14c18bd668 | |||
f779f0345e |
@ -16,7 +16,7 @@ func (app *appContext) checkInvites() {
|
|||||||
currentTime := time.Now()
|
currentTime := time.Now()
|
||||||
app.storage.loadInvites()
|
app.storage.loadInvites()
|
||||||
changed := false
|
changed := false
|
||||||
for code, data := range app.storage.invites {
|
for code, data := range app.storage.GetInvites() {
|
||||||
expiry := data.ValidTill
|
expiry := data.ValidTill
|
||||||
if !currentTime.After(expiry) {
|
if !currentTime.After(expiry) {
|
||||||
continue
|
continue
|
||||||
@ -54,7 +54,7 @@ func (app *appContext) checkInvites() {
|
|||||||
wait.Wait()
|
wait.Wait()
|
||||||
}
|
}
|
||||||
changed = true
|
changed = true
|
||||||
delete(app.storage.invites, code)
|
app.storage.DeleteInvitesKey(code)
|
||||||
}
|
}
|
||||||
if changed {
|
if changed {
|
||||||
app.storage.storeInvites()
|
app.storage.storeInvites()
|
||||||
@ -65,7 +65,7 @@ func (app *appContext) checkInvite(code string, used bool, username string) bool
|
|||||||
currentTime := time.Now()
|
currentTime := time.Now()
|
||||||
app.storage.loadInvites()
|
app.storage.loadInvites()
|
||||||
changed := false
|
changed := false
|
||||||
inv, match := app.storage.invites[code]
|
inv, match := app.storage.GetInvitesKey(code)
|
||||||
if !match {
|
if !match {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -105,21 +105,21 @@ func (app *appContext) checkInvite(code string, used bool, username string) bool
|
|||||||
}
|
}
|
||||||
changed = true
|
changed = true
|
||||||
match = false
|
match = false
|
||||||
delete(app.storage.invites, code)
|
app.storage.DeleteInvitesKey(code)
|
||||||
} else if used {
|
} else if used {
|
||||||
changed = true
|
changed = true
|
||||||
del := false
|
del := false
|
||||||
newInv := inv
|
newInv := inv
|
||||||
if newInv.RemainingUses == 1 {
|
if newInv.RemainingUses == 1 {
|
||||||
del = true
|
del = true
|
||||||
delete(app.storage.invites, code)
|
app.storage.DeleteInvitesKey(code)
|
||||||
} else if newInv.RemainingUses != 0 {
|
} else if newInv.RemainingUses != 0 {
|
||||||
// 0 means infinite i guess?
|
// 0 means infinite i guess?
|
||||||
newInv.RemainingUses--
|
newInv.RemainingUses--
|
||||||
}
|
}
|
||||||
newInv.UsedBy = append(newInv.UsedBy, []string{username, strconv.FormatInt(currentTime.Unix(), 10)})
|
newInv.UsedBy = append(newInv.UsedBy, []string{username, strconv.FormatInt(currentTime.Unix(), 10)})
|
||||||
if !del {
|
if !del {
|
||||||
app.storage.invites[code] = newInv
|
app.storage.SetInvitesKey(code, newInv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if changed {
|
if changed {
|
||||||
@ -219,7 +219,7 @@ func (app *appContext) GenerateInvite(gc *gin.Context) {
|
|||||||
invite.Profile = "Default"
|
invite.Profile = "Default"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
app.storage.invites[inviteCode] = invite
|
app.storage.SetInvitesKey(inviteCode, invite)
|
||||||
app.storage.storeInvites()
|
app.storage.storeInvites()
|
||||||
respondBool(200, true, gc)
|
respondBool(200, true, gc)
|
||||||
}
|
}
|
||||||
@ -236,7 +236,7 @@ func (app *appContext) GetInvites(gc *gin.Context) {
|
|||||||
app.storage.loadInvites()
|
app.storage.loadInvites()
|
||||||
app.checkInvites()
|
app.checkInvites()
|
||||||
var invites []inviteDTO
|
var invites []inviteDTO
|
||||||
for code, inv := range app.storage.invites {
|
for code, inv := range app.storage.GetInvites() {
|
||||||
_, months, days, hours, minutes, _ := timeDiff(inv.ValidTill, currentTime)
|
_, months, days, hours, minutes, _ := timeDiff(inv.ValidTill, currentTime)
|
||||||
invite := inviteDTO{
|
invite := inviteDTO{
|
||||||
Code: code,
|
Code: code,
|
||||||
@ -335,9 +335,9 @@ func (app *appContext) SetProfile(gc *gin.Context) {
|
|||||||
respond(500, "Profile not found", gc)
|
respond(500, "Profile not found", gc)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
inv := app.storage.invites[req.Invite]
|
inv, _ := app.storage.GetInvitesKey(req.Invite)
|
||||||
inv.Profile = req.Profile
|
inv.Profile = req.Profile
|
||||||
app.storage.invites[req.Invite] = inv
|
app.storage.SetInvitesKey(req.Invite, inv)
|
||||||
app.storage.storeInvites()
|
app.storage.storeInvites()
|
||||||
respondBool(200, true, gc)
|
respondBool(200, true, gc)
|
||||||
}
|
}
|
||||||
@ -359,7 +359,7 @@ func (app *appContext) SetNotify(gc *gin.Context) {
|
|||||||
app.debug.Printf("%s: Notification settings change requested", code)
|
app.debug.Printf("%s: Notification settings change requested", code)
|
||||||
app.storage.loadInvites()
|
app.storage.loadInvites()
|
||||||
app.storage.loadEmails()
|
app.storage.loadEmails()
|
||||||
invite, ok := app.storage.invites[code]
|
invite, ok := app.storage.GetInvitesKey(code)
|
||||||
if !ok {
|
if !ok {
|
||||||
app.err.Printf("%s Notification setting change failed: Invalid code", code)
|
app.err.Printf("%s Notification setting change failed: Invalid code", code)
|
||||||
respond(400, "Invalid invite code", gc)
|
respond(400, "Invalid invite code", gc)
|
||||||
@ -398,7 +398,7 @@ func (app *appContext) SetNotify(gc *gin.Context) {
|
|||||||
changed = true
|
changed = true
|
||||||
}
|
}
|
||||||
if changed {
|
if changed {
|
||||||
app.storage.invites[code] = invite
|
app.storage.SetInvitesKey(code, invite)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if changed {
|
if changed {
|
||||||
@ -419,9 +419,9 @@ func (app *appContext) DeleteInvite(gc *gin.Context) {
|
|||||||
gc.BindJSON(&req)
|
gc.BindJSON(&req)
|
||||||
app.debug.Printf("%s: Deletion requested", req.Code)
|
app.debug.Printf("%s: Deletion requested", req.Code)
|
||||||
var ok bool
|
var ok bool
|
||||||
_, ok = app.storage.invites[req.Code]
|
_, ok = app.storage.GetInvitesKey(req.Code)
|
||||||
if ok {
|
if ok {
|
||||||
delete(app.storage.invites, req.Code)
|
app.storage.DeleteInvitesKey(req.Code)
|
||||||
app.storage.storeInvites()
|
app.storage.storeInvites()
|
||||||
app.info.Printf("%s: Invite deleted", req.Code)
|
app.info.Printf("%s: Invite deleted", req.Code)
|
||||||
respondBool(200, true, gc)
|
respondBool(200, true, gc)
|
||||||
|
@ -460,7 +460,7 @@ func (app *appContext) TelegramVerified(gc *gin.Context) {
|
|||||||
// @tags Other
|
// @tags Other
|
||||||
func (app *appContext) TelegramVerifiedInvite(gc *gin.Context) {
|
func (app *appContext) TelegramVerifiedInvite(gc *gin.Context) {
|
||||||
code := gc.Param("invCode")
|
code := gc.Param("invCode")
|
||||||
if _, ok := app.storage.invites[code]; !ok {
|
if _, ok := app.storage.GetInvitesKey(code); !ok {
|
||||||
respondBool(401, false, gc)
|
respondBool(401, false, gc)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -484,7 +484,7 @@ func (app *appContext) TelegramVerifiedInvite(gc *gin.Context) {
|
|||||||
// @tags Other
|
// @tags Other
|
||||||
func (app *appContext) DiscordVerifiedInvite(gc *gin.Context) {
|
func (app *appContext) DiscordVerifiedInvite(gc *gin.Context) {
|
||||||
code := gc.Param("invCode")
|
code := gc.Param("invCode")
|
||||||
if _, ok := app.storage.invites[code]; !ok {
|
if _, ok := app.storage.GetInvitesKey(code); !ok {
|
||||||
respondBool(401, false, gc)
|
respondBool(401, false, gc)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -513,7 +513,7 @@ func (app *appContext) DiscordServerInvite(gc *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
code := gc.Param("invCode")
|
code := gc.Param("invCode")
|
||||||
if _, ok := app.storage.invites[code]; !ok {
|
if _, ok := app.storage.GetInvitesKey(code); !ok {
|
||||||
respondBool(401, false, gc)
|
respondBool(401, false, gc)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -537,7 +537,7 @@ func (app *appContext) DiscordServerInvite(gc *gin.Context) {
|
|||||||
// @tags Other
|
// @tags Other
|
||||||
func (app *appContext) MatrixSendPIN(gc *gin.Context) {
|
func (app *appContext) MatrixSendPIN(gc *gin.Context) {
|
||||||
code := gc.Param("invCode")
|
code := gc.Param("invCode")
|
||||||
if _, ok := app.storage.invites[code]; !ok {
|
if _, ok := app.storage.GetInvitesKey(code); !ok {
|
||||||
respondBool(401, false, gc)
|
respondBool(401, false, gc)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -575,7 +575,7 @@ func (app *appContext) MatrixSendPIN(gc *gin.Context) {
|
|||||||
// @tags Other
|
// @tags Other
|
||||||
func (app *appContext) MatrixCheckPIN(gc *gin.Context) {
|
func (app *appContext) MatrixCheckPIN(gc *gin.Context) {
|
||||||
code := gc.Param("invCode")
|
code := gc.Param("invCode")
|
||||||
if _, ok := app.storage.invites[code]; !ok {
|
if _, ok := app.storage.GetInvitesKey(code); !ok {
|
||||||
app.debug.Println("Matrix: Invite code was invalid")
|
app.debug.Println("Matrix: Invite code was invalid")
|
||||||
respondBool(401, false, gc)
|
respondBool(401, false, gc)
|
||||||
return
|
return
|
||||||
|
29
api-users.go
29
api-users.go
@ -227,14 +227,10 @@ func (app *appContext) newUser(req newUserDTO, confirmed bool) (f errorFunc, suc
|
|||||||
}
|
}
|
||||||
if emailEnabled && app.config.Section("email_confirmation").Key("enabled").MustBool(false) && !confirmed {
|
if emailEnabled && app.config.Section("email_confirmation").Key("enabled").MustBool(false) && !confirmed {
|
||||||
claims := jwt.MapClaims{
|
claims := jwt.MapClaims{
|
||||||
"valid": true,
|
"valid": true,
|
||||||
"invite": req.Code,
|
"invite": req.Code,
|
||||||
"email": req.Email,
|
"exp": time.Now().Add(30 * time.Minute).Unix(),
|
||||||
"username": req.Username,
|
"type": "confirmation",
|
||||||
"password": req.Password,
|
|
||||||
"telegramPIN": req.TelegramPIN,
|
|
||||||
"exp": time.Now().Add(time.Hour * 12).Unix(),
|
|
||||||
"type": "confirmation",
|
|
||||||
}
|
}
|
||||||
tk := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
tk := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||||
key, err := tk.SignedString([]byte(os.Getenv("JFA_SECRET")))
|
key, err := tk.SignedString([]byte(os.Getenv("JFA_SECRET")))
|
||||||
@ -246,10 +242,17 @@ func (app *appContext) newUser(req newUserDTO, confirmed bool) (f errorFunc, suc
|
|||||||
success = false
|
success = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
inv := app.storage.invites[req.Code]
|
if app.ConfirmationKeys == nil {
|
||||||
inv.Keys = append(inv.Keys, key)
|
app.ConfirmationKeys = map[string]map[string]newUserDTO{}
|
||||||
app.storage.invites[req.Code] = inv
|
}
|
||||||
app.storage.storeInvites()
|
cKeys, ok := app.ConfirmationKeys[req.Code]
|
||||||
|
if !ok {
|
||||||
|
cKeys = map[string]newUserDTO{}
|
||||||
|
}
|
||||||
|
cKeys[key] = req
|
||||||
|
app.confirmationKeysLock.Lock()
|
||||||
|
app.ConfirmationKeys[req.Code] = cKeys
|
||||||
|
app.confirmationKeysLock.Unlock()
|
||||||
f = func(gc *gin.Context) {
|
f = func(gc *gin.Context) {
|
||||||
app.debug.Printf("%s: Email confirmation required", req.Code)
|
app.debug.Printf("%s: Email confirmation required", req.Code)
|
||||||
respond(401, "confirmEmail", gc)
|
respond(401, "confirmEmail", gc)
|
||||||
@ -276,7 +279,7 @@ func (app *appContext) newUser(req newUserDTO, confirmed bool) (f errorFunc, suc
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
app.storage.loadProfiles()
|
app.storage.loadProfiles()
|
||||||
invite := app.storage.invites[req.Code]
|
invite, _ := app.storage.GetInvitesKey(req.Code)
|
||||||
app.checkInvite(req.Code, true, req.Username)
|
app.checkInvite(req.Code, true, req.Username)
|
||||||
if emailEnabled && app.config.Section("notifications").Key("enabled").MustBool(false) {
|
if emailEnabled && app.config.Section("notifications").Key("enabled").MustBool(false) {
|
||||||
for address, settings := range invite.Notify {
|
for address, settings := range invite.Notify {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" class="{{ .cssClass }}">
|
<html lang="en" class="{{ .cssClass }}">
|
||||||
<head>
|
<head>
|
||||||
<link rel="stylesheet" type="text/css" href="css/{{ .cssVersion }}bundle.css">
|
<link rel="stylesheet" type="text/css" href="{{ .urlBase }}/css/{{ .cssVersion }}bundle.css">
|
||||||
{{ template "header.html" . }}
|
{{ template "header.html" . }}
|
||||||
<title>Invalid Code - jfa-go</title>
|
<title>Invalid Code - jfa-go</title>
|
||||||
</head>
|
</head>
|
||||||
|
45
main.go
45
main.go
@ -17,6 +17,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -90,27 +91,29 @@ type appContext struct {
|
|||||||
adminUsers []User
|
adminUsers []User
|
||||||
invalidTokens []string
|
invalidTokens []string
|
||||||
// Keeping jf name because I can't think of a better one
|
// Keeping jf name because I can't think of a better one
|
||||||
jf *mediabrowser.MediaBrowser
|
jf *mediabrowser.MediaBrowser
|
||||||
authJf *mediabrowser.MediaBrowser
|
authJf *mediabrowser.MediaBrowser
|
||||||
ombi *ombi.Ombi
|
ombi *ombi.Ombi
|
||||||
datePattern string
|
datePattern string
|
||||||
timePattern string
|
timePattern string
|
||||||
storage Storage
|
storage Storage
|
||||||
validator Validator
|
validator Validator
|
||||||
email *Emailer
|
email *Emailer
|
||||||
telegram *TelegramDaemon
|
telegram *TelegramDaemon
|
||||||
discord *DiscordDaemon
|
discord *DiscordDaemon
|
||||||
matrix *MatrixDaemon
|
matrix *MatrixDaemon
|
||||||
info, debug, err *logger.Logger
|
info, debug, err *logger.Logger
|
||||||
host string
|
host string
|
||||||
port int
|
port int
|
||||||
version string
|
version string
|
||||||
URLBase string
|
URLBase string
|
||||||
updater *Updater
|
updater *Updater
|
||||||
newUpdate bool // Whether whatever's in update is new.
|
newUpdate bool // Whether whatever's in update is new.
|
||||||
tag Tag
|
tag Tag
|
||||||
update Update
|
update Update
|
||||||
internalPWRs map[string]InternalPWR
|
internalPWRs map[string]InternalPWR
|
||||||
|
ConfirmationKeys map[string]map[string]newUserDTO // Map of invite code to jwt to request
|
||||||
|
confirmationKeysLock sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateSecret(length int) (string, error) {
|
func generateSecret(length int) (string, error) {
|
||||||
|
38
storage.go
38
storage.go
@ -167,6 +167,39 @@ func (st *Storage) DeleteMatrixKey(k string) {
|
|||||||
st.matrixLock.Unlock()
|
st.matrixLock.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetInvites returns a copy of the store.
|
||||||
|
func (st *Storage) GetInvites() Invites {
|
||||||
|
if st.invites == nil {
|
||||||
|
st.invites = Invites{}
|
||||||
|
}
|
||||||
|
return st.invites
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetInvitesKey returns the value stored in the store's key.
|
||||||
|
func (st *Storage) GetInvitesKey(k string) (Invite, bool) {
|
||||||
|
v, ok := st.invites[k]
|
||||||
|
return v, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetInvitesKey stores value v in key k.
|
||||||
|
func (st *Storage) SetInvitesKey(k string, v Invite) {
|
||||||
|
st.invitesLock.Lock()
|
||||||
|
if st.invites == nil {
|
||||||
|
st.invites = Invites{}
|
||||||
|
}
|
||||||
|
st.invites[k] = v
|
||||||
|
st.storeInvites()
|
||||||
|
st.invitesLock.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteInvitesKey deletes value at key k.
|
||||||
|
func (st *Storage) DeleteInvitesKey(k string) {
|
||||||
|
st.invitesLock.Lock()
|
||||||
|
delete(st.invites, k)
|
||||||
|
st.storeInvites()
|
||||||
|
st.invitesLock.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
type TelegramUser struct {
|
type TelegramUser struct {
|
||||||
ChatID int64
|
ChatID int64
|
||||||
Username string
|
Username string
|
||||||
@ -245,7 +278,6 @@ type Invite struct {
|
|||||||
Notify map[string]map[string]bool `json:"notify"`
|
Notify map[string]map[string]bool `json:"notify"`
|
||||||
Profile string `json:"profile"`
|
Profile string `json:"profile"`
|
||||||
Label string `json:"label,omitempty"`
|
Label string `json:"label,omitempty"`
|
||||||
Keys []string `json:"keys,omitempty"`
|
|
||||||
Captchas map[string]*captcha.Data // Map of Captcha IDs to answers
|
Captchas map[string]*captcha.Data // Map of Captcha IDs to answers
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -932,14 +964,10 @@ func (st *Storage) loadLangTelegram(filesystems ...fs.FS) error {
|
|||||||
type Invites map[string]Invite
|
type Invites map[string]Invite
|
||||||
|
|
||||||
func (st *Storage) loadInvites() error {
|
func (st *Storage) loadInvites() error {
|
||||||
st.invitesLock.Lock()
|
|
||||||
defer st.invitesLock.Unlock()
|
|
||||||
return loadJSON(st.invite_path, &st.invites)
|
return loadJSON(st.invite_path, &st.invites)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (st *Storage) storeInvites() error {
|
func (st *Storage) storeInvites() error {
|
||||||
st.invitesLock.Lock()
|
|
||||||
defer st.invitesLock.Unlock()
|
|
||||||
return storeJSON(st.invite_path, st.invites)
|
return storeJSON(st.invite_path, st.invites)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
78
views.go
78
views.go
@ -342,9 +342,10 @@ func (app *appContext) ResetPassword(gc *gin.Context) {
|
|||||||
func (app *appContext) GetCaptcha(gc *gin.Context) {
|
func (app *appContext) GetCaptcha(gc *gin.Context) {
|
||||||
code := gc.Param("invCode")
|
code := gc.Param("invCode")
|
||||||
captchaID := gc.Param("captchaID")
|
captchaID := gc.Param("captchaID")
|
||||||
inv, ok := app.storage.invites[code]
|
inv, ok := app.storage.GetInvitesKey(code)
|
||||||
if !ok {
|
if !ok {
|
||||||
gcHTML(gc, 404, "invalidCode.html", gin.H{
|
gcHTML(gc, 404, "invalidCode.html", gin.H{
|
||||||
|
"urlBase": app.getURLBase(gc),
|
||||||
"cssClass": app.cssClass,
|
"cssClass": app.cssClass,
|
||||||
"cssVersion": cssVersion,
|
"cssVersion": cssVersion,
|
||||||
"contactMessage": app.config.Section("ui").Key("contact_message").String(),
|
"contactMessage": app.config.Section("ui").Key("contact_message").String(),
|
||||||
@ -376,9 +377,10 @@ func (app *appContext) GetCaptcha(gc *gin.Context) {
|
|||||||
// @tags Users
|
// @tags Users
|
||||||
func (app *appContext) GenCaptcha(gc *gin.Context) {
|
func (app *appContext) GenCaptcha(gc *gin.Context) {
|
||||||
code := gc.Param("invCode")
|
code := gc.Param("invCode")
|
||||||
inv, ok := app.storage.invites[code]
|
inv, ok := app.storage.GetInvitesKey(code)
|
||||||
if !ok {
|
if !ok {
|
||||||
gcHTML(gc, 404, "invalidCode.html", gin.H{
|
gcHTML(gc, 404, "invalidCode.html", gin.H{
|
||||||
|
"urlBase": app.getURLBase(gc),
|
||||||
"cssClass": app.cssClass,
|
"cssClass": app.cssClass,
|
||||||
"cssVersion": cssVersion,
|
"cssVersion": cssVersion,
|
||||||
"contactMessage": app.config.Section("ui").Key("contact_message").String(),
|
"contactMessage": app.config.Section("ui").Key("contact_message").String(),
|
||||||
@ -395,8 +397,7 @@ func (app *appContext) GenCaptcha(gc *gin.Context) {
|
|||||||
}
|
}
|
||||||
captchaID := genAuthToken()
|
captchaID := genAuthToken()
|
||||||
inv.Captchas[captchaID] = capt
|
inv.Captchas[captchaID] = capt
|
||||||
app.storage.invites[code] = inv
|
app.storage.SetInvitesKey(code, inv)
|
||||||
app.storage.storeInvites()
|
|
||||||
gc.JSON(200, genCaptchaDTO{captchaID})
|
gc.JSON(200, genCaptchaDTO{captchaID})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -405,7 +406,7 @@ func (app *appContext) verifyCaptcha(code, id, text string) bool {
|
|||||||
reCAPTCHA := app.config.Section("captcha").Key("recaptcha").MustBool(false)
|
reCAPTCHA := app.config.Section("captcha").Key("recaptcha").MustBool(false)
|
||||||
if !reCAPTCHA {
|
if !reCAPTCHA {
|
||||||
// internal CAPTCHA
|
// internal CAPTCHA
|
||||||
inv, ok := app.storage.invites[code]
|
inv, ok := app.storage.GetInvitesKey(code)
|
||||||
if !ok || inv.Captchas == nil {
|
if !ok || inv.Captchas == nil {
|
||||||
app.debug.Printf("Couldn't find invite \"%s\"", code)
|
app.debug.Printf("Couldn't find invite \"%s\"", code)
|
||||||
return false
|
return false
|
||||||
@ -472,9 +473,10 @@ func (app *appContext) VerifyCaptcha(gc *gin.Context) {
|
|||||||
code := gc.Param("invCode")
|
code := gc.Param("invCode")
|
||||||
captchaID := gc.Param("captchaID")
|
captchaID := gc.Param("captchaID")
|
||||||
text := gc.Param("text")
|
text := gc.Param("text")
|
||||||
inv, ok := app.storage.invites[code]
|
inv, ok := app.storage.GetInvitesKey(code)
|
||||||
if !ok {
|
if !ok {
|
||||||
gcHTML(gc, 404, "invalidCode.html", gin.H{
|
gcHTML(gc, 404, "invalidCode.html", gin.H{
|
||||||
|
"urlBase": app.getURLBase(gc),
|
||||||
"cssClass": app.cssClass,
|
"cssClass": app.cssClass,
|
||||||
"cssVersion": cssVersion,
|
"cssVersion": cssVersion,
|
||||||
"contactMessage": app.config.Section("ui").Key("contact_message").String(),
|
"contactMessage": app.config.Section("ui").Key("contact_message").String(),
|
||||||
@ -503,9 +505,10 @@ func (app *appContext) InviteProxy(gc *gin.Context) {
|
|||||||
lang := app.getLang(gc, FormPage, app.storage.lang.chosenUserLang)
|
lang := app.getLang(gc, FormPage, app.storage.lang.chosenUserLang)
|
||||||
/* Don't actually check if the invite is valid, just if it exists, just so the page loads quicker. Invite is actually checked on submit anyway. */
|
/* Don't actually check if the invite is valid, just if it exists, just so the page loads quicker. Invite is actually checked on submit anyway. */
|
||||||
// if app.checkInvite(code, false, "") {
|
// if app.checkInvite(code, false, "") {
|
||||||
inv, ok := app.storage.invites[code]
|
inv, ok := app.storage.GetInvitesKey(code)
|
||||||
if !ok {
|
if !ok {
|
||||||
gcHTML(gc, 404, "invalidCode.html", gin.H{
|
gcHTML(gc, 404, "invalidCode.html", gin.H{
|
||||||
|
"urlBase": app.getURLBase(gc),
|
||||||
"cssClass": app.cssClass,
|
"cssClass": app.cssClass,
|
||||||
"cssVersion": cssVersion,
|
"cssVersion": cssVersion,
|
||||||
"contactMessage": app.config.Section("ui").Key("contact_message").String(),
|
"contactMessage": app.config.Section("ui").Key("contact_message").String(),
|
||||||
@ -513,23 +516,27 @@ func (app *appContext) InviteProxy(gc *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if key := gc.Query("key"); key != "" && app.config.Section("email_confirmation").Key("enabled").MustBool(false) {
|
if key := gc.Query("key"); key != "" && app.config.Section("email_confirmation").Key("enabled").MustBool(false) {
|
||||||
validKey := false
|
|
||||||
keyIndex := -1
|
|
||||||
for i, k := range inv.Keys {
|
|
||||||
if k == key {
|
|
||||||
validKey = true
|
|
||||||
keyIndex = i
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fail := func() {
|
fail := func() {
|
||||||
gcHTML(gc, 404, "404.html", gin.H{
|
gcHTML(gc, 404, "404.html", gin.H{
|
||||||
|
"urlBase": app.getURLBase(gc),
|
||||||
"cssClass": app.cssClass,
|
"cssClass": app.cssClass,
|
||||||
"cssVersion": cssVersion,
|
"cssVersion": cssVersion,
|
||||||
"contactMessage": app.config.Section("ui").Key("contact_message").String(),
|
"contactMessage": app.config.Section("ui").Key("contact_message").String(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if !validKey {
|
var req newUserDTO
|
||||||
|
if app.ConfirmationKeys == nil {
|
||||||
|
fail()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
invKeys, ok := app.ConfirmationKeys[code]
|
||||||
|
if !ok {
|
||||||
|
fail()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req, ok = invKeys[key]
|
||||||
|
if !ok {
|
||||||
fail()
|
fail()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -540,26 +547,17 @@ func (app *appContext) InviteProxy(gc *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
claims, ok := token.Claims.(jwt.MapClaims)
|
claims, ok := token.Claims.(jwt.MapClaims)
|
||||||
expiryUnix := int64(claims["exp"].(float64))
|
expiry := time.Unix(int64(claims["exp"].(float64)), 0)
|
||||||
if err != nil {
|
|
||||||
fail()
|
|
||||||
app.err.Printf("Failed to parse key expiry: %s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
expiry := time.Unix(expiryUnix, 0)
|
|
||||||
if !(ok && token.Valid && claims["invite"].(string) == code && claims["type"].(string) == "confirmation" && expiry.After(time.Now())) {
|
if !(ok && token.Valid && claims["invite"].(string) == code && claims["type"].(string) == "confirmation" && expiry.After(time.Now())) {
|
||||||
fail()
|
fail()
|
||||||
app.debug.Printf("Invalid key")
|
app.debug.Printf("Invalid key")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
req := newUserDTO{
|
f, success := app.newUser(req, true)
|
||||||
Email: claims["email"].(string),
|
|
||||||
Username: claims["username"].(string),
|
|
||||||
Password: claims["password"].(string),
|
|
||||||
Code: claims["invite"].(string),
|
|
||||||
}
|
|
||||||
_, success := app.newUser(req, true)
|
|
||||||
if !success {
|
if !success {
|
||||||
|
app.err.Printf("Failed to create new user")
|
||||||
|
// Not meant for us. Calling this will be a mess, but at least it might give us some information.
|
||||||
|
f(gc)
|
||||||
fail()
|
fail()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -568,22 +566,25 @@ func (app *appContext) InviteProxy(gc *gin.Context) {
|
|||||||
gc.Redirect(301, jfLink)
|
gc.Redirect(301, jfLink)
|
||||||
} else {
|
} else {
|
||||||
gcHTML(gc, http.StatusOK, "create-success.html", gin.H{
|
gcHTML(gc, http.StatusOK, "create-success.html", gin.H{
|
||||||
|
"urlBase": app.getURLBase(gc),
|
||||||
"cssClass": app.cssClass,
|
"cssClass": app.cssClass,
|
||||||
|
"cssVersion": cssVersion,
|
||||||
"strings": app.storage.lang.User[lang].Strings,
|
"strings": app.storage.lang.User[lang].Strings,
|
||||||
"successMessage": app.config.Section("ui").Key("success_message").String(),
|
"successMessage": app.config.Section("ui").Key("success_message").String(),
|
||||||
"contactMessage": app.config.Section("ui").Key("contact_message").String(),
|
"contactMessage": app.config.Section("ui").Key("contact_message").String(),
|
||||||
"jfLink": jfLink,
|
"jfLink": jfLink,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
inv, ok := app.storage.invites[code]
|
delete(invKeys, key)
|
||||||
if ok {
|
app.confirmationKeysLock.Lock()
|
||||||
l := len(inv.Keys)
|
app.ConfirmationKeys[code] = invKeys
|
||||||
inv.Keys[l-1], inv.Keys[keyIndex] = inv.Keys[keyIndex], inv.Keys[l-1]
|
app.confirmationKeysLock.Unlock()
|
||||||
app.storage.invites[code] = inv
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
email := app.storage.invites[code].SendTo
|
email := ""
|
||||||
|
if invite, ok := app.storage.GetInvitesKey(code); ok {
|
||||||
|
email = invite.SendTo
|
||||||
|
}
|
||||||
if strings.Contains(email, "Failed") || !strings.Contains(email, "@") {
|
if strings.Contains(email, "Failed") || !strings.Contains(email, "@") {
|
||||||
email = ""
|
email = ""
|
||||||
}
|
}
|
||||||
@ -657,6 +658,7 @@ func (app *appContext) InviteProxy(gc *gin.Context) {
|
|||||||
func (app *appContext) NoRouteHandler(gc *gin.Context) {
|
func (app *appContext) NoRouteHandler(gc *gin.Context) {
|
||||||
app.pushResources(gc, OtherPage)
|
app.pushResources(gc, OtherPage)
|
||||||
gcHTML(gc, 404, "404.html", gin.H{
|
gcHTML(gc, 404, "404.html", gin.H{
|
||||||
|
"urlBase": app.getURLBase(gc),
|
||||||
"cssClass": app.cssClass,
|
"cssClass": app.cssClass,
|
||||||
"cssVersion": cssVersion,
|
"cssVersion": cssVersion,
|
||||||
"contactMessage": app.config.Section("ui").Key("contact_message").String(),
|
"contactMessage": app.config.Section("ui").Key("contact_message").String(),
|
||||||
|
Loading…
Reference in New Issue
Block a user