Add API to get account two recovery status
This commit is contained in:
parent
13bae268ec
commit
09a7d557d2
|
@ -5,6 +5,7 @@ import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
b64 "encoding/base64"
|
b64 "encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/ente-io/museum/pkg/repo/accountrecovery"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
@ -137,6 +138,7 @@ func main() {
|
||||||
|
|
||||||
twoFactorRepo := &repo.TwoFactorRepository{DB: db, SecretEncryptionKey: secretEncryptionKeyBytes}
|
twoFactorRepo := &repo.TwoFactorRepository{DB: db, SecretEncryptionKey: secretEncryptionKeyBytes}
|
||||||
userAuthRepo := &repo.UserAuthRepository{DB: db}
|
userAuthRepo := &repo.UserAuthRepository{DB: db}
|
||||||
|
accountRecoveryRepo := &accountrecovery.Repository{Db: db}
|
||||||
billingRepo := &repo.BillingRepository{DB: db}
|
billingRepo := &repo.BillingRepository{DB: db}
|
||||||
userEntityRepo := &userEntityRepo.Repository{DB: db}
|
userEntityRepo := &userEntityRepo.Repository{DB: db}
|
||||||
locationTagRepository := &locationtagRepo.Repository{DB: db}
|
locationTagRepository := &locationtagRepo.Repository{DB: db}
|
||||||
|
@ -304,6 +306,7 @@ func main() {
|
||||||
usageRepo,
|
usageRepo,
|
||||||
userAuthRepo,
|
userAuthRepo,
|
||||||
twoFactorRepo,
|
twoFactorRepo,
|
||||||
|
accountRecoveryRepo,
|
||||||
passkeysRepo,
|
passkeysRepo,
|
||||||
storagBonusRepo,
|
storagBonusRepo,
|
||||||
fileRepo,
|
fileRepo,
|
||||||
|
@ -429,6 +432,10 @@ func main() {
|
||||||
publicAPI.POST("/users/two-factor/remove", userHandler.RemoveTwoFactor)
|
publicAPI.POST("/users/two-factor/remove", userHandler.RemoveTwoFactor)
|
||||||
publicAPI.POST("/users/two-factor/passkeys/begin", userHandler.BeginPasskeyAuthenticationCeremony)
|
publicAPI.POST("/users/two-factor/passkeys/begin", userHandler.BeginPasskeyAuthenticationCeremony)
|
||||||
publicAPI.POST("/users/two-factor/passkeys/finish", userHandler.FinishPasskeyAuthenticationCeremony)
|
publicAPI.POST("/users/two-factor/passkeys/finish", userHandler.FinishPasskeyAuthenticationCeremony)
|
||||||
|
privateAPI.GET("/users/two-factor/account-recovery-status", userHandler.GetAccountRecoveryStatus)
|
||||||
|
privateAPI.POST("/users/two-factor/passkeys/set-reset-challenge", userHandler.ConfigurePassKeyRecovery)
|
||||||
|
publicAPI.GET("/users/two-factor/passkeys/reset-challenge", userHandler.GetPasskeyResetChallenge)
|
||||||
|
publicAPI.POST("/users/two-factor/passkeys/reset", userHandler.ResetPasskey)
|
||||||
privateAPI.GET("/users/two-factor/status", userHandler.GetTwoFactorStatus)
|
privateAPI.GET("/users/two-factor/status", userHandler.GetTwoFactorStatus)
|
||||||
privateAPI.POST("/users/two-factor/setup", userHandler.SetupTwoFactor)
|
privateAPI.POST("/users/two-factor/setup", userHandler.SetupTwoFactor)
|
||||||
privateAPI.POST("/users/two-factor/enable", userHandler.EnableTwoFactor)
|
privateAPI.POST("/users/two-factor/enable", userHandler.EnableTwoFactor)
|
||||||
|
|
|
@ -244,6 +244,27 @@ func (h *UserHandler) GetTwoFactorStatus(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, gin.H{"status": status})
|
c.JSON(http.StatusOK, gin.H{"status": status})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *UserHandler) GetAccountRecoveryStatus(c *gin.Context) {
|
||||||
|
res, err := h.UserController.GetAccountRecoveryStatus(c)
|
||||||
|
if err != nil {
|
||||||
|
handler.Error(c, stacktrace.Propagate(err, ""))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *UserHandler) ConfigurePassKeyRecovery(c *gin.Context) {
|
||||||
|
c.JSON(http.StatusNotImplemented, gin.H{"message": "Not implemented"})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *UserHandler) GetPasskeyResetChallenge(c *gin.Context) {
|
||||||
|
c.JSON(http.StatusNotImplemented, gin.H{"message": "Not implemented"})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *UserHandler) ResetPasskey(c *gin.Context) {
|
||||||
|
c.JSON(http.StatusNotImplemented, gin.H{"message": "Not implemented"})
|
||||||
|
}
|
||||||
|
|
||||||
// SetupTwoFactor generates a two factor secret and sends it to user to setup his authenticator app with
|
// SetupTwoFactor generates a two factor secret and sends it to user to setup his authenticator app with
|
||||||
func (h *UserHandler) SetupTwoFactor(c *gin.Context) {
|
func (h *UserHandler) SetupTwoFactor(c *gin.Context) {
|
||||||
userID := auth.GetUserID(c.Request.Header)
|
userID := auth.GetUserID(c.Request.Header)
|
||||||
|
@ -352,6 +373,16 @@ func (h *UserHandler) FinishPasskeyAuthenticationCeremony(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, response)
|
c.JSON(http.StatusOK, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *UserHandler) IsPasskeyRecoveryEnabled(c *gin.Context) {
|
||||||
|
userID := auth.GetUserID(c.Request.Header)
|
||||||
|
response, err := h.UserController.GetKeyAttributeAndToken(c, userID)
|
||||||
|
if err != nil {
|
||||||
|
handler.Error(c, stacktrace.Propagate(err, ""))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, response)
|
||||||
|
}
|
||||||
|
|
||||||
// DisableTwoFactor disables the two factor authentication for a user
|
// DisableTwoFactor disables the two factor authentication for a user
|
||||||
func (h *UserHandler) DisableTwoFactor(c *gin.Context) {
|
func (h *UserHandler) DisableTwoFactor(c *gin.Context) {
|
||||||
userID := auth.GetUserID(c.Request.Header)
|
userID := auth.GetUserID(c.Request.Header)
|
||||||
|
|
13
server/pkg/controller/user/passkey.go
Normal file
13
server/pkg/controller/user/passkey.go
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ente-io/museum/ente"
|
||||||
|
"github.com/ente-io/museum/pkg/utils/auth"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetAccountRecoveryStatus returns a user's passkey reset status
|
||||||
|
func (c *UserController) GetAccountRecoveryStatus(ctx *gin.Context) (*ente.AccountRecoveryStatus, error) {
|
||||||
|
userID := auth.GetUserID(ctx.Request.Header)
|
||||||
|
return c.AccountRecoveryRepo.GetAccountRecoveryStatus(userID)
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ package user
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/ente-io/museum/pkg/repo/accountrecovery"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
cache2 "github.com/ente-io/museum/ente/cache"
|
cache2 "github.com/ente-io/museum/ente/cache"
|
||||||
|
@ -30,6 +31,7 @@ import (
|
||||||
// UserController exposes request handlers for all user related requests
|
// UserController exposes request handlers for all user related requests
|
||||||
type UserController struct {
|
type UserController struct {
|
||||||
UserRepo *repo.UserRepository
|
UserRepo *repo.UserRepository
|
||||||
|
AccountRecoveryRepo *accountrecovery.Repository
|
||||||
UsageRepo *repo.UsageRepository
|
UsageRepo *repo.UsageRepository
|
||||||
UserAuthRepo *repo.UserAuthRepository
|
UserAuthRepo *repo.UserAuthRepository
|
||||||
TwoFactorRepo *repo.TwoFactorRepository
|
TwoFactorRepo *repo.TwoFactorRepository
|
||||||
|
@ -99,6 +101,7 @@ func NewUserController(
|
||||||
usageRepo *repo.UsageRepository,
|
usageRepo *repo.UsageRepository,
|
||||||
userAuthRepo *repo.UserAuthRepository,
|
userAuthRepo *repo.UserAuthRepository,
|
||||||
twoFactorRepo *repo.TwoFactorRepository,
|
twoFactorRepo *repo.TwoFactorRepository,
|
||||||
|
accountRecoveryRepo *accountrecovery.Repository,
|
||||||
passkeyRepo *passkey.Repository,
|
passkeyRepo *passkey.Repository,
|
||||||
storageBonusRepo *storageBonusRepo.Repository,
|
storageBonusRepo *storageBonusRepo.Repository,
|
||||||
fileRepo *repo.FileRepository,
|
fileRepo *repo.FileRepository,
|
||||||
|
@ -121,6 +124,7 @@ func NewUserController(
|
||||||
return &UserController{
|
return &UserController{
|
||||||
UserRepo: userRepo,
|
UserRepo: userRepo,
|
||||||
UsageRepo: usageRepo,
|
UsageRepo: usageRepo,
|
||||||
|
AccountRecoveryRepo: accountRecoveryRepo,
|
||||||
UserAuthRepo: userAuthRepo,
|
UserAuthRepo: userAuthRepo,
|
||||||
StorageBonusRepo: storageBonusRepo,
|
StorageBonusRepo: storageBonusRepo,
|
||||||
TwoFactorRepo: twoFactorRepo,
|
TwoFactorRepo: twoFactorRepo,
|
||||||
|
|
29
server/pkg/repo/accountrecovery/repository.go
Normal file
29
server/pkg/repo/accountrecovery/repository.go
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
package accountrecovery
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"github.com/ente-io/museum/ente"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Repository struct {
|
||||||
|
Db *sql.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAccountRecoveryStatus returns `ente.AccountRecoveryStatus` for a user
|
||||||
|
func (r *Repository) GetAccountRecoveryStatus(userID int64) (*ente.AccountRecoveryStatus, error) {
|
||||||
|
var isAdminResetEnabled bool
|
||||||
|
var resetKey sql.NullString
|
||||||
|
row := r.Db.QueryRow("SELECT enable_admin_mfa_reset, pass_key_reset_key FROM account_recovery WHERE user_id = $1", userID)
|
||||||
|
err := row.Scan(&isAdminResetEnabled, &resetKey)
|
||||||
|
if err != nil {
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
// by default, admin
|
||||||
|
return &ente.AccountRecoveryStatus{
|
||||||
|
AllowAdminReset: true,
|
||||||
|
IsPassKeyResetEnabled: false,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &ente.AccountRecoveryStatus{AllowAdminReset: isAdminResetEnabled, IsPassKeyResetEnabled: resetKey.Valid}, nil
|
||||||
|
}
|
Loading…
Reference in a new issue