diff --git a/config.yml.sample b/config.yml.sample index 32c9cd05d8..b5e80b3a8a 100644 --- a/config.yml.sample +++ b/config.yml.sample @@ -30,6 +30,8 @@ service: timezone: GMT # Whether task comments should be enabled or not enabletaskcomments: true + # Whether totp is enabled. In most cases you want to leave that enabled. + enabletotp: true database: # Database type to use. Supported types are mysql, postgres and sqlite. diff --git a/docs/content/doc/setup/config.md b/docs/content/doc/setup/config.md index 7043ad6541..2eb7bcacd5 100644 --- a/docs/content/doc/setup/config.md +++ b/docs/content/doc/setup/config.md @@ -73,6 +73,8 @@ service: timezone: GMT # Whether task comments should be enabled or not enabletaskcomments: true + # Whether totp is enabled. In most cases you want to leave that enabled. + enabletotp: true database: # Database type to use. Supported types are mysql, postgres and sqlite. diff --git a/pkg/config/config.go b/pkg/config/config.go index c73dc6dce2..1c0dc8d2a3 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -48,6 +48,7 @@ const ( ServiceEnableTaskAttachments Key = `service.enabletaskattachments` ServiceTimeZone Key = `service.timezone` ServiceEnableTaskComments Key = `service.enabletaskcomments` + ServiceEnableTotp Key = `service.enabletotp` DatabaseType Key = `database.type` DatabaseHost Key = `database.host` @@ -188,6 +189,7 @@ func InitDefaultConfig() { ServiceEnableTaskAttachments.setDefault(true) ServiceTimeZone.setDefault("GMT") ServiceEnableTaskComments.setDefault(true) + ServiceEnableTotp.setDefault(true) // Database DatabaseType.setDefault("sqlite") diff --git a/pkg/routes/api/v1/info.go b/pkg/routes/api/v1/info.go index 27cc285c34..f9034f8e70 100644 --- a/pkg/routes/api/v1/info.go +++ b/pkg/routes/api/v1/info.go @@ -35,6 +35,7 @@ type vikunjaInfos struct { AvailableMigrators []string `json:"available_migrators"` TaskAttachmentsEnabled bool `json:"task_attachments_enabled"` EnabledBackgroundProviders []string `json:"enabled_background_providers"` + TotpEnabled bool `json:"totp_enabled"` } // Info is the handler to get infos about this vikunja instance @@ -53,6 +54,7 @@ func Info(c echo.Context) error { MaxFileSize: config.FilesMaxSize.GetString(), RegistrationEnabled: config.ServiceEnableRegistration.GetBool(), TaskAttachmentsEnabled: config.ServiceEnableTaskAttachments.GetBool(), + TotpEnabled: config.ServiceEnableTotp.GetBool(), } // Migrators diff --git a/pkg/routes/routes.go b/pkg/routes/routes.go index dc41778cbf..23a4a4077a 100644 --- a/pkg/routes/routes.go +++ b/pkg/routes/routes.go @@ -213,11 +213,14 @@ func registerAPIRoutes(a *echo.Group) { u.GET("s", apiv1.UserList) u.POST("/token", apiv1.RenewToken) u.POST("/settings/email", apiv1.UpdateUserEmail) - u.GET("/settings/totp", apiv1.UserTOTP) - u.POST("/settings/totp/enroll", apiv1.UserTOTPEnroll) - u.POST("/settings/totp/enable", apiv1.UserTOTPEnable) - u.POST("/settings/totp/disable", apiv1.UserTOTPDisable) - u.GET("/settings/totp/qrcode", apiv1.UserTOTPQrCode) + + if config.ServiceEnableTotp.GetBool() { + u.GET("/settings/totp", apiv1.UserTOTP) + u.POST("/settings/totp/enroll", apiv1.UserTOTPEnroll) + u.POST("/settings/totp/enable", apiv1.UserTOTPEnable) + u.POST("/settings/totp/disable", apiv1.UserTOTPDisable) + u.GET("/settings/totp/qrcode", apiv1.UserTOTPQrCode) + } listHandler := &handler.WebHandler{ EmptyStruct: func() handler.CObject { diff --git a/pkg/user/totp.go b/pkg/user/totp.go index eca41805b3..478b80ce31 100644 --- a/pkg/user/totp.go +++ b/pkg/user/totp.go @@ -17,6 +17,7 @@ package user import ( + "code.vikunja.io/api/pkg/config" "github.com/pquerna/otp" "github.com/pquerna/otp/totp" "image" @@ -46,6 +47,9 @@ type TOTPPasscode struct { // TOTPEnabledForUser checks if totp is enabled for a user - not if it is activated, use GetTOTPForUser to check that. func TOTPEnabledForUser(user *User) (bool, error) { + if !config.ServiceEnableTotp.GetBool() { + return false, nil + } return x.Where("user_id = ?", user.ID).Exist(&TOTP{}) }