owpengram-server/internal/app/auth/login_email_test.go

102 lines
3.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package auth
import (
"context"
"errors"
"testing"
"telesrv/internal/domain"
"telesrv/internal/store/memory"
)
// TestSignInWithEmailCompletesLogin 验证带 email_verification 的登录:注册账号→登出→
// 重新 sendCode→用任意邮箱验证码经 SignInWithEmail 完成登录。
func TestSignInWithEmailCompletesLogin(t *testing.T) {
ctx := context.Background()
users := memory.NewUserStore()
authz := memory.NewAuthorizationStore()
svc := NewService(users, authz, memory.NewCodeStore(), nil, nil, "12345")
var key [8]byte
key[0] = 0x42
hash, err := svc.SendCode(ctx, "+15550009001")
if err != nil {
t.Fatalf("SendCode signup: %v", err)
}
u, _, err := svc.SignUp(ctx, domain.Authorization{AuthKeyID: key}, "+15550009001", hash, "Email", "Login")
if err != nil {
t.Fatalf("SignUp: %v", err)
}
if err := svc.LogOut(ctx, key); err != nil {
t.Fatalf("LogOut: %v", err)
}
hash, err = svc.SendCode(ctx, "+15550009001")
if err != nil {
t.Fatalf("SendCode signin: %v", err)
}
got, _, needSignUp, err := svc.SignInWithEmail(ctx, domain.Authorization{AuthKeyID: key}, "+15550009001", hash, "anything-goes")
if err != nil {
t.Fatalf("SignInWithEmail: %v", err)
}
if needSignUp || got.ID != u.ID {
t.Fatalf("SignInWithEmail user=%+v needSignUp=%v, want existing user %d", got, needSignUp, u.ID)
}
bound, found, err := svc.UserID(ctx, key)
if err != nil || !found || bound != u.ID {
t.Fatalf("UserID after email signin = %d found=%v err=%v, want %d", bound, found, err, u.ID)
}
}
// TestSignInWithEmailRejectsEmptyCode 空邮箱验证码必须被拒(即使开发环境码任意,也不能空)。
func TestSignInWithEmailRejectsEmptyCode(t *testing.T) {
ctx := context.Background()
svc := NewService(memory.NewUserStore(), memory.NewAuthorizationStore(), memory.NewCodeStore(), nil, nil, "12345")
hash, err := svc.SendCode(ctx, "+15550009002")
if err != nil {
t.Fatalf("SendCode: %v", err)
}
if _, _, _, err := svc.SignInWithEmail(ctx, domain.Authorization{}, "+15550009002", hash, " "); !errors.Is(err, ErrCodeInvalid) {
t.Fatalf("SignInWithEmail empty code err = %v, want ErrCodeInvalid", err)
}
}
// TestSignInWithEmailStillHonorsTwoFactor 登录邮箱与 2FA 正交:即使走邮箱验证码,
// 开启了两步验证的账号仍停在 SESSION_PASSWORD_NEEDED不能绕过密码。
func TestSignInWithEmailStillHonorsTwoFactor(t *testing.T) {
ctx := context.Background()
passwords := memory.NewPasswordStore()
svc := NewService(memory.NewUserStore(), memory.NewAuthorizationStore(), memory.NewCodeStore(), nil, nil, "12345", WithPasswords(passwords))
var key [8]byte
key[0] = 0x43
hash, err := svc.SendCode(ctx, "+15550009003")
if err != nil {
t.Fatalf("SendCode signup: %v", err)
}
u, _, err := svc.SignUp(ctx, domain.Authorization{AuthKeyID: key}, "+15550009003", hash, "Two", "Factor")
if err != nil {
t.Fatalf("SignUp: %v", err)
}
if err := svc.LogOut(ctx, key); err != nil {
t.Fatalf("LogOut: %v", err)
}
if err := passwords.Save(ctx, u.ID, domain.PasswordSettings{HasPassword: true}); err != nil {
t.Fatalf("save password settings: %v", err)
}
hash, err = svc.SendCode(ctx, "+15550009003")
if err != nil {
t.Fatalf("SendCode signin: %v", err)
}
got, _, _, err := svc.SignInWithEmail(ctx, domain.Authorization{AuthKeyID: key}, "+15550009003", hash, "any-email-code")
if !errors.Is(err, domain.ErrSessionPasswordNeeded) {
t.Fatalf("SignInWithEmail err = %v, want ErrSessionPasswordNeeded", err)
}
if got.ID != u.ID {
t.Fatalf("SignInWithEmail user = %+v, want pending 2FA user %d", got, u.ID)
}
if bound, found, err := svc.UserID(ctx, key); err != nil || found || bound != 0 {
t.Fatalf("UserID after email signin with 2FA = %d found=%v err=%v, want not-found", bound, found, err)
}
}