166 lines
4.5 KiB
Go
166 lines
4.5 KiB
Go
package storage
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"time"
|
|
|
|
"gpt-plus/pkg/chatgpt"
|
|
)
|
|
|
|
// SaveAccount saves an AccountResult to a JSON file named {email}.json in outputDir.
|
|
func SaveAccount(outputDir string, result *chatgpt.AccountResult) error {
|
|
if err := os.MkdirAll(outputDir, 0o755); err != nil {
|
|
return fmt.Errorf("create output dir: %w", err)
|
|
}
|
|
|
|
filename := filepath.Join(outputDir, result.Email+".json")
|
|
data, err := json.MarshalIndent(result, "", " ")
|
|
if err != nil {
|
|
return fmt.Errorf("marshal account result: %w", err)
|
|
}
|
|
|
|
if err := os.WriteFile(filename, data, 0o644); err != nil {
|
|
return fmt.Errorf("write account file: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// authFile mirrors the auth.json format used by sub2api / other tools.
|
|
type authFile struct {
|
|
OpenAIAPIKey string `json:"OPENAI_API_KEY"`
|
|
AccessToken string `json:"access_token"`
|
|
IDToken string `json:"id_token"`
|
|
LastRefresh string `json:"last_refresh"`
|
|
RefreshToken string `json:"refresh_token"`
|
|
Tokens authTokens `json:"tokens"`
|
|
}
|
|
|
|
type authTokens struct {
|
|
AccessToken string `json:"access_token"`
|
|
AccountID string `json:"account_id"`
|
|
IDToken string `json:"id_token"`
|
|
LastRefresh string `json:"last_refresh"`
|
|
RefreshToken string `json:"refresh_token"`
|
|
}
|
|
|
|
// SavePlusAuthFile saves a Plus auth.json file (personal token) to outputDir/plus/.
|
|
func SavePlusAuthFile(outputDir string, result *chatgpt.AccountResult) error {
|
|
dir := filepath.Join(outputDir, "plus")
|
|
if err := os.MkdirAll(dir, 0o755); err != nil {
|
|
return fmt.Errorf("create plus output dir: %w", err)
|
|
}
|
|
|
|
now := time.Now().UTC().Format("2006-01-02T15:04:05Z")
|
|
|
|
auth := &authFile{
|
|
OpenAIAPIKey: "",
|
|
AccessToken: result.AccessToken,
|
|
IDToken: result.IDToken,
|
|
LastRefresh: now,
|
|
RefreshToken: result.RefreshToken,
|
|
Tokens: authTokens{
|
|
AccessToken: result.AccessToken,
|
|
AccountID: result.ChatGPTAccountID,
|
|
IDToken: result.IDToken,
|
|
LastRefresh: now,
|
|
RefreshToken: result.RefreshToken,
|
|
},
|
|
}
|
|
|
|
filename := filepath.Join(dir, result.Email+".auth.json")
|
|
data, err := json.MarshalIndent(auth, "", " ")
|
|
if err != nil {
|
|
return fmt.Errorf("marshal plus auth file: %w", err)
|
|
}
|
|
|
|
if err := os.WriteFile(filename, data, 0o644); err != nil {
|
|
return fmt.Errorf("write plus auth file: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// SaveTeamAuthFile saves a Team auth.json file (workspace token) to outputDir/team/.
|
|
func SaveTeamAuthFile(outputDir string, result *chatgpt.AccountResult) error {
|
|
dir := filepath.Join(outputDir, "team")
|
|
if err := os.MkdirAll(dir, 0o755); err != nil {
|
|
return fmt.Errorf("create team output dir: %w", err)
|
|
}
|
|
|
|
now := time.Now().UTC().Format("2006-01-02T15:04:05Z")
|
|
|
|
// Prefer WorkspaceToken, fallback to AccessToken
|
|
token := result.WorkspaceToken
|
|
if token == "" {
|
|
token = result.AccessToken
|
|
}
|
|
|
|
auth := &authFile{
|
|
OpenAIAPIKey: "",
|
|
AccessToken: token,
|
|
IDToken: result.IDToken,
|
|
LastRefresh: now,
|
|
RefreshToken: result.RefreshToken,
|
|
Tokens: authTokens{
|
|
AccessToken: token,
|
|
AccountID: result.TeamAccountID,
|
|
IDToken: result.IDToken,
|
|
LastRefresh: now,
|
|
RefreshToken: result.RefreshToken,
|
|
},
|
|
}
|
|
|
|
filename := filepath.Join(dir, result.Email+".auth.json")
|
|
data, err := json.MarshalIndent(auth, "", " ")
|
|
if err != nil {
|
|
return fmt.Errorf("marshal team auth file: %w", err)
|
|
}
|
|
|
|
if err := os.WriteFile(filename, data, 0o644); err != nil {
|
|
return fmt.Errorf("write team auth file: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// SaveFreeAuthFile saves a free account auth.json file (personal token) to outputDir/free/.
|
|
func SaveFreeAuthFile(outputDir string, result *chatgpt.AccountResult) error {
|
|
dir := filepath.Join(outputDir, "free")
|
|
if err := os.MkdirAll(dir, 0o755); err != nil {
|
|
return fmt.Errorf("create free output dir: %w", err)
|
|
}
|
|
|
|
now := time.Now().UTC().Format("2006-01-02T15:04:05Z")
|
|
|
|
auth := &authFile{
|
|
OpenAIAPIKey: "",
|
|
AccessToken: result.AccessToken,
|
|
IDToken: result.IDToken,
|
|
LastRefresh: now,
|
|
RefreshToken: result.RefreshToken,
|
|
Tokens: authTokens{
|
|
AccessToken: result.AccessToken,
|
|
AccountID: result.ChatGPTAccountID,
|
|
IDToken: result.IDToken,
|
|
LastRefresh: now,
|
|
RefreshToken: result.RefreshToken,
|
|
},
|
|
}
|
|
|
|
filename := filepath.Join(dir, result.Email+".auth.json")
|
|
data, err := json.MarshalIndent(auth, "", " ")
|
|
if err != nil {
|
|
return fmt.Errorf("marshal free auth file: %w", err)
|
|
}
|
|
|
|
if err := os.WriteFile(filename, data, 0o644); err != nil {
|
|
return fmt.Errorf("write free auth file: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|