Skip to content

Commit b43ee62

Browse files
committed
fix CI/CD Error
1 parent 106b20c commit b43ee62

6 files changed

Lines changed: 155 additions & 2 deletions

File tree

backend/internal/server/middleware/admin_auth_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ func TestAdminAuthJWTValidatesTokenVersion(t *testing.T) {
1919
gin.SetMode(gin.TestMode)
2020

2121
cfg := &config.Config{JWT: config.JWTConfig{Secret: "test-secret", ExpireHour: 1}}
22-
authService := service.NewAuthService(nil, nil, nil, cfg, nil, nil, nil, nil, nil, nil)
22+
authService := service.NewAuthService(nil, nil, nil, nil, cfg, nil, nil, nil, nil, nil, nil)
2323

2424
admin := &service.User{
2525
ID: 1,

backend/internal/server/middleware/jwt_auth_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ func newJWTTestEnv(users map[int64]*service.User) (*gin.Engine, *service.AuthSer
4040
cfg.JWT.AccessTokenExpireMinutes = 60
4141

4242
userRepo := &stubJWTUserRepo{users: users}
43-
authSvc := service.NewAuthService(userRepo, nil, nil, cfg, nil, nil, nil, nil, nil, nil)
43+
authSvc := service.NewAuthService(nil, userRepo, nil, nil, cfg, nil, nil, nil, nil, nil, nil)
4444
userSvc := service.NewUserService(userRepo, nil, nil)
4545
mw := NewJWTAuthMiddleware(authSvc, userSvc)
4646

backend/internal/service/auth_service.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,11 @@ func (s *AuthService) LoginOrRegisterOAuthWithTokenPair(ctx context.Context, ema
647647
} else {
648648
user = newUser
649649
s.assignDefaultSubscriptions(ctx, user.ID)
650+
if invitationRedeemCode != nil {
651+
if err := s.redeemRepo.Use(ctx, invitationRedeemCode.ID, user.ID); err != nil {
652+
return nil, nil, ErrInvitationCodeInvalid
653+
}
654+
}
650655
}
651656
}
652657
} else {
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
//go:build unit
2+
3+
package service
4+
5+
import (
6+
"testing"
7+
"time"
8+
9+
"github.com/Wei-Shaw/sub2api/internal/config"
10+
"github.com/golang-jwt/jwt/v5"
11+
"github.com/stretchr/testify/require"
12+
)
13+
14+
func newAuthServiceForPendingOAuthTest() *AuthService {
15+
cfg := &config.Config{
16+
JWT: config.JWTConfig{
17+
Secret: "test-secret-pending-oauth",
18+
ExpireHour: 1,
19+
},
20+
}
21+
return NewAuthService(nil, nil, nil, nil, cfg, nil, nil, nil, nil, nil, nil)
22+
}
23+
24+
// TestVerifyPendingOAuthToken_ValidToken 验证正常签发的 pending token 可以被成功解析。
25+
func TestVerifyPendingOAuthToken_ValidToken(t *testing.T) {
26+
svc := newAuthServiceForPendingOAuthTest()
27+
28+
token, err := svc.CreatePendingOAuthToken("user@example.com", "alice")
29+
require.NoError(t, err)
30+
require.NotEmpty(t, token)
31+
32+
email, username, err := svc.VerifyPendingOAuthToken(token)
33+
require.NoError(t, err)
34+
require.Equal(t, "user@example.com", email)
35+
require.Equal(t, "alice", username)
36+
}
37+
38+
// TestVerifyPendingOAuthToken_RegularJWTRejected 用普通 access token 尝试验证,应返回 ErrInvalidToken。
39+
func TestVerifyPendingOAuthToken_RegularJWTRejected(t *testing.T) {
40+
svc := newAuthServiceForPendingOAuthTest()
41+
42+
// 签发一个普通 access token(JWTClaims,无 Purpose 字段)
43+
accessToken, err := svc.GenerateToken(&User{
44+
ID: 1,
45+
Email: "user@example.com",
46+
Role: RoleUser,
47+
})
48+
require.NoError(t, err)
49+
50+
_, _, err = svc.VerifyPendingOAuthToken(accessToken)
51+
require.ErrorIs(t, err, ErrInvalidToken)
52+
}
53+
54+
// TestVerifyPendingOAuthToken_WrongPurpose 手动构造 purpose 字段不匹配的 JWT,应返回 ErrInvalidToken。
55+
func TestVerifyPendingOAuthToken_WrongPurpose(t *testing.T) {
56+
svc := newAuthServiceForPendingOAuthTest()
57+
58+
now := time.Now()
59+
claims := &pendingOAuthClaims{
60+
Email: "user@example.com",
61+
Username: "alice",
62+
Purpose: "some_other_purpose",
63+
RegisteredClaims: jwt.RegisteredClaims{
64+
ExpiresAt: jwt.NewNumericDate(now.Add(10 * time.Minute)),
65+
IssuedAt: jwt.NewNumericDate(now),
66+
NotBefore: jwt.NewNumericDate(now),
67+
},
68+
}
69+
tok := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
70+
tokenStr, err := tok.SignedString([]byte(svc.cfg.JWT.Secret))
71+
require.NoError(t, err)
72+
73+
_, _, err = svc.VerifyPendingOAuthToken(tokenStr)
74+
require.ErrorIs(t, err, ErrInvalidToken)
75+
}
76+
77+
// TestVerifyPendingOAuthToken_MissingPurpose 手动构造无 purpose 字段的 JWT(模拟旧 token),应返回 ErrInvalidToken。
78+
func TestVerifyPendingOAuthToken_MissingPurpose(t *testing.T) {
79+
svc := newAuthServiceForPendingOAuthTest()
80+
81+
now := time.Now()
82+
claims := &pendingOAuthClaims{
83+
Email: "user@example.com",
84+
Username: "alice",
85+
Purpose: "", // 旧 token 无此字段,反序列化后为零值
86+
RegisteredClaims: jwt.RegisteredClaims{
87+
ExpiresAt: jwt.NewNumericDate(now.Add(10 * time.Minute)),
88+
IssuedAt: jwt.NewNumericDate(now),
89+
NotBefore: jwt.NewNumericDate(now),
90+
},
91+
}
92+
tok := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
93+
tokenStr, err := tok.SignedString([]byte(svc.cfg.JWT.Secret))
94+
require.NoError(t, err)
95+
96+
_, _, err = svc.VerifyPendingOAuthToken(tokenStr)
97+
require.ErrorIs(t, err, ErrInvalidToken)
98+
}
99+
100+
// TestVerifyPendingOAuthToken_ExpiredToken 过期 token 应返回 ErrInvalidToken。
101+
func TestVerifyPendingOAuthToken_ExpiredToken(t *testing.T) {
102+
svc := newAuthServiceForPendingOAuthTest()
103+
104+
past := time.Now().Add(-1 * time.Hour)
105+
claims := &pendingOAuthClaims{
106+
Email: "user@example.com",
107+
Username: "alice",
108+
Purpose: pendingOAuthPurpose,
109+
RegisteredClaims: jwt.RegisteredClaims{
110+
ExpiresAt: jwt.NewNumericDate(past),
111+
IssuedAt: jwt.NewNumericDate(past.Add(-10 * time.Minute)),
112+
NotBefore: jwt.NewNumericDate(past.Add(-10 * time.Minute)),
113+
},
114+
}
115+
tok := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
116+
tokenStr, err := tok.SignedString([]byte(svc.cfg.JWT.Secret))
117+
require.NoError(t, err)
118+
119+
_, _, err = svc.VerifyPendingOAuthToken(tokenStr)
120+
require.ErrorIs(t, err, ErrInvalidToken)
121+
}
122+
123+
// TestVerifyPendingOAuthToken_WrongSecret 不同密钥签发的 token 应返回 ErrInvalidToken。
124+
func TestVerifyPendingOAuthToken_WrongSecret(t *testing.T) {
125+
other := NewAuthService(nil, nil, nil, nil, &config.Config{
126+
JWT: config.JWTConfig{Secret: "other-secret"},
127+
}, nil, nil, nil, nil, nil, nil)
128+
129+
token, err := other.CreatePendingOAuthToken("user@example.com", "alice")
130+
require.NoError(t, err)
131+
132+
svc := newAuthServiceForPendingOAuthTest()
133+
_, _, err = svc.VerifyPendingOAuthToken(token)
134+
require.ErrorIs(t, err, ErrInvalidToken)
135+
}
136+
137+
// TestVerifyPendingOAuthToken_TooLong 超长 token 应返回 ErrInvalidToken。
138+
func TestVerifyPendingOAuthToken_TooLong(t *testing.T) {
139+
svc := newAuthServiceForPendingOAuthTest()
140+
giant := make([]byte, maxTokenLength+1)
141+
for i := range giant {
142+
giant[i] = 'a'
143+
}
144+
_, _, err := svc.VerifyPendingOAuthToken(string(giant))
145+
require.ErrorIs(t, err, ErrInvalidToken)
146+
}

backend/internal/service/auth_service_register_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ func newAuthService(repo *userRepoStub, settings map[string]string, emailCache E
130130
}
131131

132132
return NewAuthService(
133+
nil, // entClient
133134
repo,
134135
nil, // redeemRepo
135136
nil, // refreshTokenCache

backend/internal/service/auth_service_turnstile_register_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ func newAuthServiceForRegisterTurnstileTest(settings map[string]string, verifier
4343
turnstileService := NewTurnstileService(settingService, verifier)
4444

4545
return NewAuthService(
46+
nil, // entClient
4647
&userRepoStub{},
4748
nil, // redeemRepo
4849
nil, // refreshTokenCache

0 commit comments

Comments
 (0)