/
gql.go
115 lines (86 loc) · 2.86 KB
/
gql.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package clients
import (
"github.com/envsecrets/envsecrets/cli/config"
configCommons "github.com/envsecrets/envsecrets/cli/config/commons"
"github.com/envsecrets/envsecrets/internal/auth"
"github.com/envsecrets/envsecrets/internal/clients"
"github.com/envsecrets/envsecrets/internal/context"
"github.com/sirupsen/logrus"
"github.com/machinebox/graphql"
)
type GQLClient struct {
*clients.GQLClient
log *logrus.Logger
}
type GQLConfig struct {
BaseURL string
Authorization string
Logger *logrus.Logger
}
func NewGQLClient(config *GQLConfig) *GQLClient {
client := clients.NewGQLClient(&clients.GQLConfig{
BaseURL: NHOST_GRAPHQL_URL,
Authorization: config.Authorization,
ErrorHandler: getErrorHandler(config.Logger),
})
response := GQLClient{
GQLClient: client,
}
if config.Logger != nil {
response.log = config.Logger
} else {
response.log = logrus.New()
}
return &response
}
func (c *GQLClient) Do(ctx context.ServiceContext, req *graphql.Request, resp interface{}) error {
// Parse the error
if err := c.GQLClient.Do(ctx, req, &resp); err != nil {
return err
}
return nil
}
func getErrorHandler(log *logrus.Logger) func(*clients.GQLClient, error) error {
return func(c *clients.GQLClient, err error) error {
apiError := ParseExternal(err)
// If it's a JWTExpired error,
// refresh the JWT and re-call the request.
switch apiError.Type {
case ErrorTypeJWTExpired, ErrorTypeMalformedHeader:
log.Debug("JWT Expired or Header Malformed. Refreshing...")
// Fetch account configuration
accountConfigPayload, err := config.GetService().Load(configCommons.AccountConfig)
if err != nil {
return New(err, "Failed to load account config", ErrorTypeInvalidAccountConfiguration, ErrorSourceSystem).ToError()
}
accountConfig := accountConfigPayload.(*configCommons.Account)
ctx := context.NewContext(&context.Config{Type: context.CLIContext})
// Initialize a new Nhost client.
nhostClient := NewNhostClient(&NhostConfig{
Logger: log,
})
authResponse, refreshErr := auth.GetService().RefreshToken(ctx, nhostClient.NhostClient, &auth.RefreshTokenOptions{
RefreshToken: accountConfig.RefreshToken,
})
if refreshErr != nil {
return New(refreshErr, "Failed to refresh access token", ErrorTypeInvalidToken, ErrorSourceNhost).ToError()
}
// Save the refreshed account config
refreshConfig := configCommons.Account{
AccessToken: authResponse.AccessToken,
RefreshToken: authResponse.RefreshToken,
User: authResponse.User,
}
if err := config.GetService().Save(refreshConfig, configCommons.AccountConfig); err != nil {
return err
}
// Update the authorization header in client.
c.Authorization = "Bearer " + authResponse.AccessToken
// Re-do the request
c.RedoRequestOnError = true
default:
return apiError.ToError()
}
return nil
}
}