feat: add i18n support and batch JSON credentials import

This commit is contained in:
Quorinex
2026-02-06 21:54:04 +08:00
parent d05bd00207
commit d6fa49f24e
9 changed files with 1730 additions and 673 deletions

View File

@@ -57,7 +57,7 @@ func StartBuilderIdLogin(region string) (*BuilderIdSession, error) {
regReq, _ := http.NewRequest("POST", oidcBase+"/client/register", bytes.NewReader(regBody))
regReq.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 30 * time.Second}
client := httpClient
regResp, err := client.Do(regReq)
if err != nil {
return nil, fmt.Errorf("register client failed: %v", err)
@@ -175,7 +175,7 @@ func PollBuilderIdAuth(sessionID string) (accessToken, refreshToken, clientID, c
tokenReq, _ := http.NewRequest("POST", oidcBase+"/token", bytes.NewReader(tokenBody))
tokenReq.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 30 * time.Second}
client := httpClient
tokenResp, err := client.Do(tokenReq)
if err != nil {
return "", "", "", "", "", 0, "", fmt.Errorf("token request failed: %v", err)

20
auth/http_client.go Normal file
View File

@@ -0,0 +1,20 @@
// Package auth 提供认证相关功能的 HTTP 客户端
package auth
import (
"net/http"
"time"
)
// 全局 HTTP 客户端,复用连接池
// 用于所有 auth 模块的 HTTP 请求
var httpClient = &http.Client{
Timeout: 30 * time.Second,
Transport: &http.Transport{
MaxIdleConns: 50, // 最大空闲连接数
MaxIdleConnsPerHost: 10, // 每个 Host 最大空闲连接数
IdleConnTimeout: 90 * time.Second, // 空闲连接超时
DisableCompression: false, // 启用压缩
ForceAttemptHTTP2: true, // 尝试使用 HTTP/2
},
}

View File

@@ -170,8 +170,7 @@ func registerOIDCClient(oidcBase, startUrl, redirectUri string) (clientID, clien
req, _ := http.NewRequest("POST", oidcBase+"/client/register", bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 30 * time.Second}
resp, err := client.Do(req)
resp, err := httpClient.Do(req)
if err != nil {
return "", "", err
}
@@ -208,8 +207,7 @@ func exchangeToken(oidcBase, clientID, clientSecret, code, codeVerifier, redirec
req, _ := http.NewRequest("POST", oidcBase+"/token", bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 30 * time.Second}
resp, err := client.Do(req)
resp, err := httpClient.Do(req)
if err != nil {
return "", "", 0, err
}

View File

@@ -37,8 +37,7 @@ func refreshOIDCToken(refreshToken, clientID, clientSecret, region string) (stri
req, _ := http.NewRequest("POST", url, bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 30 * time.Second}
resp, err := client.Do(req)
resp, err := httpClient.Do(req)
if err != nil {
return "", "", 0, err
}
@@ -75,8 +74,7 @@ func refreshSocialToken(refreshToken string) (string, string, int64, error) {
req, _ := http.NewRequest("POST", url, bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 30 * time.Second}
resp, err := client.Do(req)
resp, err := httpClient.Do(req)
if err != nil {
return "", "", 0, err
}

View File

@@ -79,7 +79,7 @@ func registerDeviceClient(oidcBase, startUrl string) (clientID, clientSecret str
req, _ := http.NewRequest("POST", oidcBase+"/client/register", bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 30 * time.Second}
client := httpClient
resp, err := client.Do(req)
if err != nil {
return "", "", err
@@ -110,7 +110,7 @@ func startDeviceAuth(oidcBase, clientID, clientSecret, startUrl string) (deviceC
req, _ := http.NewRequest("POST", oidcBase+"/device_authorization", bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 30 * time.Second}
client := httpClient
resp, err := client.Do(req)
if err != nil {
return "", "", 0, err
@@ -139,7 +139,7 @@ func verifyBearerToken(portalBase, bearerToken string) error {
req.Header.Set("Authorization", "Bearer "+bearerToken)
req.Header.Set("Accept", "application/json")
client := &http.Client{Timeout: 30 * time.Second}
client := httpClient
resp, err := client.Do(req)
if err != nil {
return err
@@ -157,7 +157,7 @@ func getDeviceSessionToken(portalBase, bearerToken string) (string, error) {
req.Header.Set("Authorization", "Bearer "+bearerToken)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 30 * time.Second}
client := httpClient
resp, err := client.Do(req)
if err != nil {
return "", err
@@ -193,7 +193,7 @@ func acceptUserCode(oidcBase, userCode, deviceSessionToken string) (*deviceConte
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Referer", "https://view.awsapps.com/")
client := &http.Client{Timeout: 30 * time.Second}
client := httpClient
resp, err := client.Do(req)
if err != nil {
return nil, err
@@ -227,7 +227,7 @@ func approveAuth(oidcBase string, deviceContext *deviceContextInfo, deviceSessio
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Referer", "https://view.awsapps.com/")
client := &http.Client{Timeout: 30 * time.Second}
client := httpClient
resp, err := client.Do(req)
if err != nil {
return err
@@ -262,7 +262,7 @@ func pollForToken(oidcBase, clientID, clientSecret, deviceCode string, interval
req, _ := http.NewRequest("POST", oidcBase+"/token", bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 30 * time.Second}
client := httpClient
resp, err := client.Do(req)
if err != nil {
continue
@@ -311,7 +311,7 @@ func GetUserInfo(accessToken string) (email, userID string, err error) {
req.Header.Set("User-Agent", "aws-sdk-js/1.0.18 KiroAPIProxy")
req.Header.Set("x-amz-user-agent", "aws-sdk-js/1.0.18 KiroAPIProxy")
client := &http.Client{Timeout: 30 * time.Second}
client := httpClient
resp, err := client.Do(req)
if err != nil {
return "", "", err