diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 9d6dd92..11ae1da 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -4,7 +4,14 @@
-
+
+
+
+
+
+
+
+
diff --git a/pkg/internal/models/accounts.go b/pkg/internal/models/accounts.go
index 418d441..79505e8 100644
--- a/pkg/internal/models/accounts.go
+++ b/pkg/internal/models/accounts.go
@@ -12,14 +12,15 @@ import (
type Account struct {
BaseModel
- Name string `json:"name" gorm:"uniqueIndex"`
- Nick string `json:"nick"`
- Description string `json:"description"`
- Avatar *string `json:"avatar"`
- Banner *string `json:"banner"`
- ConfirmedAt *time.Time `json:"confirmed_at"`
- SuspendedAt *time.Time `json:"suspended_at"`
- PermNodes datatypes.JSONMap `json:"perm_nodes"`
+ Name string `json:"name" gorm:"uniqueIndex"`
+ Nick string `json:"nick"`
+ Description string `json:"description"`
+ Avatar *string `json:"avatar"`
+ Banner *string `json:"banner"`
+ ConfirmedAt *time.Time `json:"confirmed_at"`
+ SuspendedAt *time.Time `json:"suspended_at"`
+ PermNodes datatypes.JSONMap `json:"perm_nodes"`
+ AuthConfig datatypes.JSONType[AuthConfig] `json:"auth_config"`
AutomatedBy *Account `json:"automated_by" gorm:"foreignKey:AutomatedID"`
AutomatedID *uint `json:"automated_id"`
diff --git a/pkg/internal/models/auth.go b/pkg/internal/models/auth.go
index 239e9d2..3c4dd8d 100644
--- a/pkg/internal/models/auth.go
+++ b/pkg/internal/models/auth.go
@@ -7,6 +7,10 @@ import (
"gorm.io/datatypes"
)
+type AuthConfig struct {
+ MaximumAuthSteps int `json:"maximum_auth_steps" validate:"required,min=1"`
+}
+
type AuthFactorType = int8
const (
diff --git a/pkg/internal/server/api/index.go b/pkg/internal/server/api/index.go
index aff118b..953d3ec 100644
--- a/pkg/internal/server/api/index.go
+++ b/pkg/internal/server/api/index.go
@@ -26,6 +26,8 @@ func MapAPIs(app *fiber.App, baseURL string) {
preferences := api.Group("/preferences").Name("Preferences API")
{
+ preferences.Get("/auth", getAuthConfig)
+ preferences.Put("/auth", updateAuthConfig)
preferences.Get("/notifications", getNotificationPreference)
preferences.Put("/notifications", updateNotificationPreference)
}
diff --git a/pkg/internal/server/api/preferences_api.go b/pkg/internal/server/api/preferences_api.go
index a821952..bbc2145 100644
--- a/pkg/internal/server/api/preferences_api.go
+++ b/pkg/internal/server/api/preferences_api.go
@@ -1,12 +1,45 @@
package api
import (
+ "git.solsynth.dev/hydrogen/passport/pkg/internal/database"
"git.solsynth.dev/hydrogen/passport/pkg/internal/models"
"git.solsynth.dev/hydrogen/passport/pkg/internal/server/exts"
"git.solsynth.dev/hydrogen/passport/pkg/internal/services"
"github.com/gofiber/fiber/v2"
+ "gorm.io/datatypes"
)
+func getAuthConfig(c *fiber.Ctx) error {
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
+ user := c.Locals("user").(models.Account)
+
+ return c.JSON(user.AuthConfig)
+}
+
+func updateAuthConfig(c *fiber.Ctx) error {
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
+ user := c.Locals("user").(models.Account)
+
+ var data models.AuthConfig
+ if err := exts.BindAndValidate(c, &data); err != nil {
+ return fiber.NewError(fiber.StatusBadRequest, err.Error())
+ }
+
+ user.AuthConfig = datatypes.NewJSONType(data)
+
+ if err := database.C.Save(&user).Error; err != nil {
+ return fiber.NewError(fiber.StatusInternalServerError, err.Error())
+ } else {
+ services.InvalidAuthCacheWithUser(user.ID)
+ }
+
+ return c.JSON(user.AuthConfig)
+}
+
func getNotificationPreference(c *fiber.Ctx) error {
if err := exts.EnsureAuthenticated(c); err != nil {
return err
diff --git a/pkg/internal/services/ticket.go b/pkg/internal/services/ticket.go
index 6f407dd..b8cb054 100644
--- a/pkg/internal/services/ticket.go
+++ b/pkg/internal/services/ticket.go
@@ -54,7 +54,11 @@ func NewTicket(user models.Account, ip, ua string) (models.AuthTicket, error) {
if count := CountUserFactor(user.ID); count <= 0 {
return ticket, fmt.Errorf("specified user didn't enable sign in")
} else {
+ cfg := user.AuthConfig.Data()
steps = min(steps, int(count))
+ if cfg.MaximumAuthSteps >= 1 {
+ steps = min(steps, cfg.MaximumAuthSteps)
+ }
}
ticket = models.AuthTicket{