Compare commits
No commits in common. "a3cfebab307a87bc895d7b1c1f0e6632a708562c" and "593410c1378e87409d94977d306872243fef1c1e" have entirely different histories.
a3cfebab30
...
593410c137
2
db/db.go
2
db/db.go
|
@ -53,7 +53,7 @@ func Init() {
|
|||
}
|
||||
|
||||
// Automatically migrate the database schema based on the model definitions.
|
||||
err = db.Migrator().AutoMigrate(&model.Account{}, &model.Key{}, &model.KeyChallenge{}, &model.LoginSession{})
|
||||
err = db.Migrator().AutoMigrate(&model.Account{}, &model.Key{}, &model.KeyChallenge{})
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("Database setup failed database type: %s \n", err))
|
||||
}
|
||||
|
|
4
go.mod
4
go.mod
|
@ -3,7 +3,6 @@ module git.lumeweb.com/LumeWeb/portal
|
|||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/go-playground/validator/v10 v10.13.0
|
||||
github.com/iris-contrib/swagger v0.0.0-20230311205341-32127a753a68
|
||||
github.com/joomcode/errorx v1.1.0
|
||||
github.com/kataras/iris/v12 v12.2.0
|
||||
|
@ -50,8 +49,6 @@ require (
|
|||
github.com/go-openapi/jsonreference v0.20.2 // indirect
|
||||
github.com/go-openapi/spec v0.20.9 // indirect
|
||||
github.com/go-openapi/swag v0.22.3 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-sql-driver/mysql v1.7.1 // indirect
|
||||
github.com/gobwas/httphead v0.1.0 // indirect
|
||||
github.com/gobwas/pool v0.2.1 // indirect
|
||||
|
@ -79,7 +76,6 @@ require (
|
|||
github.com/klauspost/compress v1.16.5 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
||||
github.com/klauspost/reedsolomon v1.11.7 // indirect
|
||||
github.com/leodido/go-urn v1.2.3 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mailgun/raymond/v2 v2.0.48 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
|
|
10
go.sum
10
go.sum
|
@ -150,13 +150,6 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh
|
|||
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
|
||||
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.13.0 h1:cFRQdfaSMCOSfGCCLB20MHvuoHb/s5G8L5pu2ppK5AQ=
|
||||
github.com/go-playground/validator/v10 v10.13.0/go.mod h1:dwu7+CG8/CtBiJFZDz4e+5Upb6OLw04gtBYw0mcG/z4=
|
||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
|
||||
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
|
@ -323,8 +316,6 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
|||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
|
||||
github.com/leodido/go-urn v1.2.3 h1:6BE2vPT0lqoz3fmOesHZiaiFh7889ssCo2GMvLCfiuA=
|
||||
github.com/leodido/go-urn v1.2.3/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||
|
@ -429,7 +420,6 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
|||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
|
||||
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
|
||||
github.com/swaggo/swag v1.16.1 h1:fTNRhKstPKxcnoKsytm4sahr8FaYzUcT7i1/3nd/fBg=
|
||||
|
|
21
main.go
21
main.go
|
@ -6,7 +6,6 @@ import (
|
|||
"git.lumeweb.com/LumeWeb/portal/db"
|
||||
_ "git.lumeweb.com/LumeWeb/portal/docs"
|
||||
"git.lumeweb.com/LumeWeb/portal/service"
|
||||
"git.lumeweb.com/LumeWeb/portal/validator"
|
||||
"github.com/iris-contrib/swagger"
|
||||
"github.com/iris-contrib/swagger/swaggerFiles"
|
||||
"github.com/kataras/iris/v12"
|
||||
|
@ -41,27 +40,22 @@ func main() {
|
|||
// Create a new Iris app instance
|
||||
app := iris.New()
|
||||
|
||||
app.Validator = validator.Get()
|
||||
|
||||
// Enable Gzip compression for responses
|
||||
app.Use(iris.Compression)
|
||||
|
||||
// Serve static files from the embedded directory at the app's root path
|
||||
app.HandleDir("/", embedFrontend)
|
||||
|
||||
api := app.Party("/api")
|
||||
v1 := api.Party("/v1")
|
||||
|
||||
// Register the AccountService with the MVC framework and attach it to the "/api/account" path
|
||||
mvc.Configure(v1.Party("/account"), func(app *mvc.Application) {
|
||||
mvc.Configure(app.Party("/api/account"), func(app *mvc.Application) {
|
||||
app.Handle(new(service.AccountService))
|
||||
})
|
||||
|
||||
mvc.Configure(v1.Party("/auth"), func(app *mvc.Application) {
|
||||
mvc.Configure(app.Party("/api/auth"), func(app *mvc.Application) {
|
||||
app.Handle(new(service.AuthService))
|
||||
})
|
||||
|
||||
swaggerConfig := swagger.Config{
|
||||
config := swagger.Config{
|
||||
// The url pointing to API definition.
|
||||
URL: "http://localhost:8080/swagger/doc.json",
|
||||
DeepLinking: true,
|
||||
|
@ -70,7 +64,7 @@ func main() {
|
|||
// The UI prefix URL (see route).
|
||||
Prefix: "/swagger",
|
||||
}
|
||||
swaggerUI := swagger.Handler(swaggerFiles.Handler, swaggerConfig)
|
||||
swaggerUI := swagger.Handler(swaggerFiles.Handler, config)
|
||||
|
||||
app.Get("/swagger", swaggerUI)
|
||||
// And the wildcard one for index.html, *.js, *.css and e.t.c.
|
||||
|
@ -80,10 +74,5 @@ func main() {
|
|||
//go renterd.Main()
|
||||
|
||||
// Start the Iris app and listen for incoming requests on port 80
|
||||
log.Fatal(app.Listen(":8080", func(app *iris.Application) {
|
||||
routes := app.GetRoutes()
|
||||
for _, route := range routes {
|
||||
log.Println(route)
|
||||
}
|
||||
}))
|
||||
log.Fatal(app.Listen(":80"))
|
||||
}
|
||||
|
|
|
@ -10,7 +10,8 @@ type Key struct {
|
|||
ID uint `gorm:"primaryKey"`
|
||||
AccountID uint
|
||||
Account Account
|
||||
Pubkey string
|
||||
PublicKey string
|
||||
PrivateKey string
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
|
|
@ -1,55 +1,22 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"crypto/ed25519"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"git.lumeweb.com/LumeWeb/portal/db"
|
||||
"git.lumeweb.com/LumeWeb/portal/model"
|
||||
_validator "git.lumeweb.com/LumeWeb/portal/validator"
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/kataras/iris/v12"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"gorm.io/gorm"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
type AccountService struct {
|
||||
Ctx iris.Context
|
||||
ctx iris.Context
|
||||
}
|
||||
|
||||
type RegisterRequest struct {
|
||||
Email string `json:"email" validate:"required"`
|
||||
Email string `json:"email"`
|
||||
Password string `json:"password"`
|
||||
Pubkey string `json:"pubkey"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
jsonValidator := _validator.Get()
|
||||
|
||||
jsonValidator.RegisterStructValidation(ValidateRegisterRequest, RegisterRequest{})
|
||||
}
|
||||
|
||||
func ValidateRegisterRequest(structLevel validator.StructLevel) {
|
||||
|
||||
request := structLevel.Current().Interface().(RegisterRequest)
|
||||
|
||||
pubkey := len(request.Pubkey) == 0
|
||||
pass := len(request.Password) == 0
|
||||
|
||||
if pubkey == pass {
|
||||
structLevel.ReportError(reflect.ValueOf(request.Email), "email", "Email", "emailorpubkey", "")
|
||||
structLevel.ReportError(reflect.ValueOf(request.Pubkey), "pubkey", "Pubkey", "emailorpubkey", "")
|
||||
}
|
||||
|
||||
if !pubkey {
|
||||
pubkeyBytes, err := hex.DecodeString(request.Pubkey)
|
||||
if err != nil || len(pubkeyBytes) != ed25519.PublicKeySize {
|
||||
structLevel.ReportError(reflect.ValueOf(request.Pubkey), "pubkey", "Pubkey", "pubkey", "")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
Pubkey []byte `json:"pubkey"`
|
||||
}
|
||||
|
||||
func hashPassword(password string) (string, error) {
|
||||
|
@ -67,62 +34,46 @@ func hashPassword(password string) (string, error) {
|
|||
func (a *AccountService) PostRegister() {
|
||||
var r RegisterRequest
|
||||
|
||||
if err := a.Ctx.ReadJSON(&r); err != nil {
|
||||
a.Ctx.StopWithError(iris.StatusBadRequest, err)
|
||||
if err := a.ctx.ReadJSON(&r); err != nil {
|
||||
a.ctx.StopWithError(iris.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Hash the password before saving it to the database.
|
||||
hashedPassword, err := hashPassword(r.Password)
|
||||
if err != nil {
|
||||
a.ctx.StopWithError(iris.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Check if an account with the same email address already exists.
|
||||
existingAccount := model.Account{}
|
||||
err := db.Get().Where("email = ?", r.Email).First(&existingAccount).Error
|
||||
err = db.Get().Where("email = ?", r.Email).First(&existingAccount).Error
|
||||
if err == nil {
|
||||
// An account with the same email address already exists.
|
||||
// Return an error response to the client.
|
||||
a.Ctx.StopWithError(iris.StatusConflict, errors.New("an account with this email address already exists"))
|
||||
a.ctx.StopWithError(iris.StatusConflict, errors.New("an account with this email address already exists"))
|
||||
return
|
||||
} else if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
// An unexpected error occurred while querying the database.
|
||||
// Return an error response to the client.
|
||||
a.Ctx.StopWithError(iris.StatusInternalServerError, err)
|
||||
a.ctx.StopWithError(iris.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Create a new Account model with the provided email and hashed password.
|
||||
account := model.Account{
|
||||
Email: r.Email,
|
||||
Password: &hashedPassword,
|
||||
}
|
||||
|
||||
// Hash the password before saving it to the database.
|
||||
if len(r.Password) > 0 {
|
||||
hashedPassword, err := hashPassword(r.Password)
|
||||
// Save the new account to the database.
|
||||
err = db.Get().Create(&account).Error
|
||||
if err != nil {
|
||||
a.Ctx.StopWithError(iris.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
account.Password = &hashedPassword
|
||||
}
|
||||
|
||||
err = db.Get().Transaction(func(tx *gorm.DB) error {
|
||||
// do some database operations in the transaction (use 'tx' from this point, not 'db')
|
||||
if err := tx.Create(&account).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(r.Pubkey) > 0 {
|
||||
if err := tx.Create(&model.Key{Account: account, Pubkey: r.Pubkey}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// return nil will commit the whole transaction
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
a.Ctx.StopWithError(iris.StatusInternalServerError, err)
|
||||
a.ctx.StopWithError(iris.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Return a success response to the client.
|
||||
a.Ctx.StatusCode(iris.StatusCreated)
|
||||
a.ctx.StatusCode(iris.StatusCreated)
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ func init() {
|
|||
}
|
||||
|
||||
type AuthService struct {
|
||||
Ctx iris.Context
|
||||
ctx iris.Context
|
||||
}
|
||||
|
||||
type LoginRequest struct {
|
||||
|
@ -136,101 +136,101 @@ func (a *AuthService) PostLogin() {
|
|||
var r LoginRequest
|
||||
|
||||
// Read the login request from the client.
|
||||
if err := a.Ctx.ReadJSON(&r); err != nil {
|
||||
a.Ctx.StopWithError(iris.StatusBadRequest, err)
|
||||
if err := a.ctx.ReadJSON(&r); err != nil {
|
||||
a.ctx.StopWithError(iris.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Retrieve the account for the given email.
|
||||
account := model.Account{}
|
||||
if err := db.Get().Where("email = ?", r.Email).First(&account).Error; err != nil {
|
||||
a.Ctx.StopWithError(iris.StatusBadRequest, errors.New("invalid email or password"))
|
||||
a.ctx.StopWithError(iris.StatusBadRequest, errors.New("invalid email or password"))
|
||||
return
|
||||
}
|
||||
|
||||
// Verify the provided password against the hashed password stored in the database.
|
||||
if err := verifyPassword(*account.Password, r.Password); err != nil {
|
||||
a.Ctx.StopWithError(iris.StatusBadRequest, errors.New("invalid email or password"))
|
||||
a.ctx.StopWithError(iris.StatusBadRequest, errors.New("invalid email or password"))
|
||||
return
|
||||
}
|
||||
|
||||
// Generate a JWT token for the authenticated user.
|
||||
token, err := generateAndSaveLoginToken(account.ID, 24*time.Hour)
|
||||
if err != nil {
|
||||
a.Ctx.StopWithError(iris.StatusInternalServerError, fmt.Errorf("failed to generate token: %s", err))
|
||||
a.ctx.StopWithError(iris.StatusInternalServerError, fmt.Errorf("failed to generate token: %s", err))
|
||||
return
|
||||
}
|
||||
|
||||
// Return the JWT token to the client.
|
||||
err = a.Ctx.JSON(&LoginResponse{Token: token})
|
||||
err = a.ctx.JSON(&LoginResponse{Token: token})
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("Error with login attempt: %s \n", err))
|
||||
}
|
||||
}
|
||||
|
||||
// PostChallenge handles the POST /api/auth/pubkey/challenge request to generate a challenge for a user's public key.
|
||||
// PostChallenge handles the POST /api/auth/pubkey-challenge request to generate a challenge for a user's public key.
|
||||
func (a *AuthService) PostPubkeyChallenge() {
|
||||
var r LoginRequest
|
||||
|
||||
// Read the login request from the client.
|
||||
if err := a.Ctx.ReadJSON(&r); err != nil {
|
||||
a.Ctx.StopWithError(iris.StatusBadRequest, err)
|
||||
if err := a.ctx.ReadJSON(&r); err != nil {
|
||||
a.ctx.StopWithError(iris.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Retrieve the account for the given email.
|
||||
account := model.Account{}
|
||||
if err := db.Get().Where("email = ?", r.Email).First(&account).Error; err != nil {
|
||||
a.Ctx.StopWithError(iris.StatusBadRequest, errors.New("invalid email or password"))
|
||||
a.ctx.StopWithError(iris.StatusBadRequest, errors.New("invalid email or password"))
|
||||
return
|
||||
}
|
||||
|
||||
// Generate a random challenge string.
|
||||
challenge, err := generateAndSaveChallengeToken(account.ID, time.Minute)
|
||||
if err != nil {
|
||||
a.Ctx.StopWithError(iris.StatusInternalServerError, errors.New("failed to generate challenge"))
|
||||
a.ctx.StopWithError(iris.StatusInternalServerError, errors.New("failed to generate challenge"))
|
||||
return
|
||||
}
|
||||
|
||||
// Return the challenge to the client.
|
||||
err = a.Ctx.JSON(&ChallengeResponse{Challenge: challenge})
|
||||
err = a.ctx.JSON(&ChallengeResponse{Challenge: challenge})
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("Error with challenge request: %s \n", err))
|
||||
}
|
||||
}
|
||||
|
||||
// PostKeyLogin handles the POST /api/auth/pubkey/login request to authenticate a user using a public key challenge and return a JWT token.
|
||||
// PostKeyLogin handles the POST /api/auth/pubkey-login request to authenticate a user using a public key challenge and return a JWT token.
|
||||
func (a *AuthService) PostPubkeyLogin() {
|
||||
var r PubkeyLoginRequest
|
||||
|
||||
// Read the key login request from the client.
|
||||
if err := a.Ctx.ReadJSON(&r); err != nil {
|
||||
a.Ctx.StopWithError(iris.StatusBadRequest, err)
|
||||
if err := a.ctx.ReadJSON(&r); err != nil {
|
||||
a.ctx.StopWithError(iris.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Retrieve the key challenge for the given challenge.
|
||||
challenge := model.KeyChallenge{}
|
||||
if err := db.Get().Where("challenge = ?", r.Challenge).Preload("Key").First(&challenge).Error; err != nil {
|
||||
a.Ctx.StopWithError(iris.StatusBadRequest, errorx.RejectedOperation.New("invalid key challenge"))
|
||||
a.ctx.StopWithError(iris.StatusBadRequest, errorx.RejectedOperation.New("invalid key challenge"))
|
||||
return
|
||||
}
|
||||
|
||||
verifiedToken, err := jwt.Verify(jwt.HS256, sharedKey, []byte(r.Challenge), blocklist)
|
||||
if err != nil {
|
||||
a.Ctx.StopWithError(iris.StatusBadRequest, errorx.RejectedOperation.New("invalid key challenge"))
|
||||
a.ctx.StopWithError(iris.StatusBadRequest, errorx.RejectedOperation.New("invalid key challenge"))
|
||||
return
|
||||
}
|
||||
|
||||
rawPubKey, err := hex.DecodeString(r.Pubkey)
|
||||
if err != nil {
|
||||
a.Ctx.StopWithError(iris.StatusBadRequest, errorx.RejectedOperation.New("invalid pubkey"))
|
||||
a.ctx.StopWithError(iris.StatusBadRequest, errorx.RejectedOperation.New("invalid pubkey"))
|
||||
return
|
||||
}
|
||||
|
||||
rawSignature, err := hex.DecodeString(r.Signature)
|
||||
if err != nil {
|
||||
a.Ctx.StopWithError(iris.StatusBadRequest, errorx.RejectedOperation.New("invalid signature"))
|
||||
a.ctx.StopWithError(iris.StatusBadRequest, errorx.RejectedOperation.New("invalid signature"))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -238,29 +238,29 @@ func (a *AuthService) PostPubkeyLogin() {
|
|||
|
||||
// Verify the challenge signature.
|
||||
if !ed25519.Verify(publicKeyDecoded, []byte(r.Challenge), rawSignature) {
|
||||
a.Ctx.StopWithError(iris.StatusBadRequest, errorx.RejectedOperation.New("invalid challenge"))
|
||||
a.ctx.StopWithError(iris.StatusBadRequest, errorx.RejectedOperation.New("invalid challenge"))
|
||||
}
|
||||
|
||||
// Generate a JWT token for the authenticated user.
|
||||
token, err := generateAndSaveLoginToken(challenge.AccountID, 24*time.Hour)
|
||||
if err != nil {
|
||||
a.Ctx.StopWithError(iris.StatusInternalServerError, errorx.RejectedOperation.Wrap(err, "failed to generate token"))
|
||||
a.ctx.StopWithError(iris.StatusInternalServerError, errorx.RejectedOperation.Wrap(err, "failed to generate token"))
|
||||
return
|
||||
}
|
||||
|
||||
err = blocklist.InvalidateToken(verifiedToken.Token, verifiedToken.StandardClaims)
|
||||
if err != nil {
|
||||
a.Ctx.StopWithError(iris.StatusInternalServerError, errorx.RejectedOperation.Wrap(err, "failed to invalidate token"))
|
||||
a.ctx.StopWithError(iris.StatusInternalServerError, errorx.RejectedOperation.Wrap(err, "failed to invalidate token"))
|
||||
return
|
||||
}
|
||||
|
||||
if err := db.Get().Delete(&challenge).Error; err != nil {
|
||||
a.Ctx.StopWithError(iris.StatusBadRequest, errorx.RejectedOperation.New("failed to delete key challenge"))
|
||||
a.ctx.StopWithError(iris.StatusBadRequest, errorx.RejectedOperation.New("failed to delete key challenge"))
|
||||
return
|
||||
}
|
||||
|
||||
// Return the JWT token to the client.
|
||||
err = a.Ctx.JSON(&LoginResponse{Token: token})
|
||||
err = a.ctx.JSON(&LoginResponse{Token: token})
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("Error with login attempt: %s \n", err))
|
||||
}
|
||||
|
@ -272,15 +272,15 @@ func (a *AuthService) PostLogout() {
|
|||
var r LogoutRequest
|
||||
|
||||
// Read the logout request from the client.
|
||||
if err := a.Ctx.ReadJSON(&r); err != nil {
|
||||
a.Ctx.StopWithError(iris.StatusBadRequest, err)
|
||||
if err := a.ctx.ReadJSON(&r); err != nil {
|
||||
a.ctx.StopWithError(iris.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Verify the provided token.
|
||||
claims, err := jwt.Verify(jwt.HS256, sharedKey, []byte(r.Token), blocklist)
|
||||
if err != nil {
|
||||
a.Ctx.StopWithError(iris.StatusBadRequest, errors.New("invalid token"))
|
||||
a.ctx.StopWithError(iris.StatusBadRequest, errors.New("invalid token"))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -290,5 +290,5 @@ func (a *AuthService) PostLogout() {
|
|||
}
|
||||
|
||||
// Return a success response to the client.
|
||||
a.Ctx.StatusCode(iris.StatusNoContent)
|
||||
a.ctx.StatusCode(iris.StatusNoContent)
|
||||
}
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
package validator
|
||||
|
||||
import (
|
||||
"github.com/go-playground/validator/v10"
|
||||
)
|
||||
|
||||
var v *validator.Validate
|
||||
|
||||
func init() {
|
||||
v = validator.New()
|
||||
}
|
||||
|
||||
func Get() *validator.Validate {
|
||||
return v
|
||||
}
|
Loading…
Reference in New Issue