diff --git a/auth-new/errors.go b/auth-new/errors.go index 0b6289c..5e8fe14 100644 --- a/auth-new/errors.go +++ b/auth-new/errors.go @@ -10,5 +10,18 @@ var ( ErrInvalidCombination = errors.New("invalid account and token combination") ErrProcessTimeout = errors.New("authentication process timed out") // A user may not login, for whatever reason - ErrCantLogin = errors.New("user can't login") + ErrCantLogin = errors.New("user can't login") + ErrDecryptionFailure = errors.New("failed to decrypt content") ) + +type CombinedError struct { + Err1, Err2 error +} + +func (c *CombinedError) Is(e error) bool { + return errors.Is(e, c.Err1) || errors.Is(e, c.Err2) +} + +func (c *CombinedError) Error() string { + return c.Err1.Error() + " + " + c.Err2.Error() +} diff --git a/auth-new/totp.go b/auth-new/totp.go index c89c1c4..a08061b 100644 --- a/auth-new/totp.go +++ b/auth-new/totp.go @@ -27,7 +27,7 @@ func (a *Authenticator) PerformTotpLogin( if err != nil { return LoginNextFailure, "", other.Error("auth", "failed to find account", err) } - secrets := sliceutils.Map( + encryptedSecrets := sliceutils.Map( sliceutils.Filter(acc.AuthMethods, func(t models.UserAuthMethod) bool { return t.AuthMethod == models.AuthMethodGAuth }), @@ -35,6 +35,18 @@ func (a *Authenticator) PerformTotpLogin( return string(t.Token) }, ) + secrets := []string{} + for _, key := range encryptedSecrets { + decrypted, err := Decrypt([]byte(config.GlobalConfig.Storage.EncryptionKey), []byte(key)) + if err != nil { + return 0, "", other.Error( + "auth", + "failed to decrypt secret", + &CombinedError{ErrDecryptionFailure, err}, + ) + } + secrets = append(secrets, string(decrypted)) + } found := false for _, secret := range secrets { if totp.Validate(totpToken, secret) { @@ -91,10 +103,17 @@ func (a *Authenticator) StartTotpRegistration( return nil, err } secret := key.Secret() + encryptedSecret, err := Encrypt( + []byte(config.GlobalConfig.Storage.EncryptionKey), + []byte(secret), + ) + if err != nil { + return nil, other.Error("auth", "failed to encrypt secret", err) + } authToken := models.UserAuthMethod{ UserId: acc.ID, User: *acc, - Token: []byte(secret), + Token: encryptedSecret, AuthMethod: models.AuthMethodGAuth, Name: tokenName + totpUnverifiedSuffix, }