@@ -9,13 +9,15 @@ const localize = nls.loadMessageBundle()
9
9
import globals from '../../shared/extensionGlobals'
10
10
import * as vscode from 'vscode'
11
11
import { AuthorizationPendingException , SlowDownException , SSOOIDCServiceException } from '@aws-sdk/client-sso-oidc'
12
- import { openSsoPortalLink , SsoToken , ClientRegistration , isExpired , SsoProfile } from './model'
12
+ import { openSsoPortalLink , SsoToken , ClientRegistration , isExpired , SsoProfile , builderIdStartUrl } from './model'
13
13
import { getCache } from './cache'
14
14
import { hasProps , hasStringProps , RequiredProps , selectFrom } from '../../shared/utilities/tsUtils'
15
15
import { CancellationError , sleep } from '../../shared/utilities/timeoutUtils'
16
16
import { OidcClient } from './clients'
17
17
import { loadOr } from '../../shared/utilities/cacheUtils'
18
- import { isClientFault , ToolkitError } from '../../shared/errors'
18
+ import { getTelemetryReason , getTelemetryResult , isClientFault , ToolkitError } from '../../shared/errors'
19
+ import { getLogger } from '../../shared/logger'
20
+ import { telemetry } from '../../shared/telemetry/telemetry'
19
21
20
22
const clientRegistrationType = 'public'
21
23
const deviceGrantType = 'urn:ietf:params:oauth:grant-type:device_code'
@@ -81,11 +83,7 @@ export class SsoAccessTokenProvider {
81
83
if ( data . registration && ! isExpired ( data . registration ) && hasProps ( data . token , 'refreshToken' ) ) {
82
84
const refreshed = await this . refreshToken ( data . token , data . registration )
83
85
84
- if ( refreshed ) {
85
- await this . cache . token . save ( this . tokenCacheKey , refreshed )
86
- }
87
-
88
- return refreshed ?. token
86
+ return refreshed . token
89
87
} else {
90
88
await this . invalidate ( )
91
89
}
@@ -95,6 +93,7 @@ export class SsoAccessTokenProvider {
95
93
const access = await this . runFlow ( )
96
94
const identity = ( await identityProvider ?.( access . token ) ) ?? this . tokenCacheKey
97
95
await this . cache . token . save ( identity , access )
96
+ await setSessionCreationDate ( this . tokenCacheKey , new Date ( ) )
98
97
99
98
return { ...access . token , identity }
100
99
}
@@ -118,9 +117,19 @@ export class SsoAccessTokenProvider {
118
117
try {
119
118
const clientInfo = selectFrom ( registration , 'clientId' , 'clientSecret' )
120
119
const response = await this . oidc . createToken ( { ...clientInfo , ...token , grantType : refreshGrantType } )
120
+ const refreshed = this . formatToken ( response , registration )
121
+ await this . cache . token . save ( this . tokenCacheKey , refreshed )
121
122
122
- return this . formatToken ( response , registration )
123
+ return refreshed
123
124
} catch ( err ) {
125
+ telemetry . aws_refreshCredentials . emit ( {
126
+ result : getTelemetryResult ( err ) ,
127
+ reason : getTelemetryReason ( err ) ,
128
+ sessionDuration : getSessionDuration ( this . tokenCacheKey ) ,
129
+ credentialType : 'bearerToken' ,
130
+ credentialSourceId : this . profile . startUrl === builderIdStartUrl ? 'awsId' : 'iamIdentityCenter' ,
131
+ } )
132
+
124
133
if ( err instanceof SSOOIDCServiceException && isClientFault ( err ) ) {
125
134
await this . cache . token . clear ( this . tokenCacheKey )
126
135
}
@@ -228,3 +237,25 @@ async function pollForTokenWithProgress<T>(
228
237
] )
229
238
)
230
239
}
240
+
241
+ const sessionCreationDateKey = '#sessionCreationDates'
242
+ async function setSessionCreationDate ( id : string , date : Date , memento = globals . context . globalState ) {
243
+ try {
244
+ await memento . update ( sessionCreationDateKey , {
245
+ ...memento . get ( sessionCreationDateKey ) ,
246
+ [ id ] : date . getTime ( ) ,
247
+ } )
248
+ } catch ( err ) {
249
+ getLogger ( ) . verbose ( 'auth: failed to set session creation date: %s' , err )
250
+ }
251
+ }
252
+
253
+ function getSessionCreationDate ( id : string , memento = globals . context . globalState ) : number | undefined {
254
+ return memento . get ( sessionCreationDateKey , { } as Record < string , number > ) [ id ]
255
+ }
256
+
257
+ function getSessionDuration ( id : string , memento = globals . context . globalState ) {
258
+ const creationDate = getSessionCreationDate ( id , memento )
259
+
260
+ return creationDate !== undefined ? Date . now ( ) - creationDate : undefined
261
+ }
0 commit comments