@@ -2,6 +2,7 @@ package auth
2
2
3
3
import (
4
4
"fmt"
5
+ "net/http"
5
6
"os"
6
7
"strconv"
7
8
"time"
@@ -132,3 +133,71 @@ func getEmailFromToken(token string) (string, error) {
132
133
133
134
return claims .Email , nil
134
135
}
136
+
137
+ // RefreshAccessToken refreshes the access token if it's expired for the user token flow.
138
+ // It returns the new access token or an error if the refresh fails.
139
+ func RefreshAccessToken (p * print.Printer ) (string , error ) {
140
+ flow , err := GetAuthFlow ()
141
+ if err != nil {
142
+ return "" , fmt .Errorf ("get authentication flow: %w" , err )
143
+ }
144
+ if flow != AUTH_FLOW_USER_TOKEN {
145
+ return "" , fmt .Errorf ("token refresh is only supported for user token flow, current flow: %s" , flow )
146
+ }
147
+
148
+ // Load tokens from storage
149
+ authFields := map [authFieldKey ]string {
150
+ ACCESS_TOKEN : "" ,
151
+ REFRESH_TOKEN : "" ,
152
+ IDP_TOKEN_ENDPOINT : "" ,
153
+ }
154
+ err = GetAuthFieldMap (authFields )
155
+ if err != nil {
156
+ return "" , fmt .Errorf ("get tokens from auth storage: %w" , err )
157
+ }
158
+
159
+ accessToken := authFields [ACCESS_TOKEN ]
160
+ refreshToken := authFields [REFRESH_TOKEN ]
161
+ tokenEndpoint := authFields [IDP_TOKEN_ENDPOINT ]
162
+
163
+ if accessToken == "" {
164
+ return "" , fmt .Errorf ("access token not set" )
165
+ }
166
+ if refreshToken == "" {
167
+ return "" , fmt .Errorf ("refresh token not set" )
168
+ }
169
+ if tokenEndpoint == "" {
170
+ return "" , fmt .Errorf ("token endpoint not set" )
171
+ }
172
+
173
+ // Check if access token is expired
174
+ accessTokenExpired , err := TokenExpired (accessToken )
175
+ if err != nil {
176
+ return "" , fmt .Errorf ("check if access token has expired: %w" , err )
177
+ }
178
+ if ! accessTokenExpired {
179
+ // Token is still valid, return it
180
+ return accessToken , nil
181
+ }
182
+
183
+ p .Debug (print .DebugLevel , "access token expired, refreshing..." )
184
+
185
+ // Create a temporary userTokenFlow to reuse the refresh logic
186
+ utf := & userTokenFlow {
187
+ printer : p ,
188
+ client : & http.Client {},
189
+ authFlow : flow ,
190
+ accessToken : accessToken ,
191
+ refreshToken : refreshToken ,
192
+ tokenEndpoint : tokenEndpoint ,
193
+ }
194
+
195
+ // Refresh the tokens
196
+ err = refreshTokens (utf )
197
+ if err != nil {
198
+ return "" , fmt .Errorf ("refresh access token: %w" , err )
199
+ }
200
+
201
+ // Return the new access token
202
+ return utf .accessToken , nil
203
+ }
0 commit comments