@@ -19,7 +19,6 @@ import {
19
19
invalidateSsoTokenRequestType ,
20
20
invalidateStsCredentialRequestType ,
21
21
ProfileKind ,
22
- UpdateProfileParams ,
23
22
updateProfileRequestType ,
24
23
SsoTokenChangedParams ,
25
24
StsCredentialChangedParams ,
@@ -50,8 +49,8 @@ import {
50
49
Profile ,
51
50
SsoSession ,
52
51
GetMfaCodeParams ,
53
- GetMfaCodeResult ,
54
52
getMfaCodeRequestType ,
53
+ GetMfaCodeResult ,
55
54
} from '@aws/language-server-runtimes/protocol'
56
55
import { LanguageClient } from 'vscode-languageclient'
57
56
import { getLogger } from '../shared/logger/logger'
@@ -125,12 +124,31 @@ export class LanguageClientAuth {
125
124
return this . #ssoCacheWatcher
126
125
}
127
126
128
- getSsoToken (
127
+ /**
128
+ * Encrypts an object
129
+ */
130
+ private async encrypt < T > ( request : T ) : Promise < string > {
131
+ const payload = new TextEncoder ( ) . encode ( JSON . stringify ( request ) )
132
+ const encrypted = await new jose . CompactEncrypt ( payload )
133
+ . setProtectedHeader ( { alg : 'dir' , enc : 'A256GCM' } )
134
+ . encrypt ( this . encryptionKey )
135
+ return encrypted
136
+ }
137
+
138
+ /**
139
+ * Decrypts an object
140
+ */
141
+ private async decrypt < T > ( request : string ) : Promise < T > {
142
+ const result = await jose . compactDecrypt ( request , this . encryptionKey )
143
+ return JSON . parse ( new TextDecoder ( ) . decode ( result . plaintext ) ) as T
144
+ }
145
+
146
+ async getSsoToken (
129
147
tokenSource : TokenSource ,
130
148
login : boolean = false ,
131
149
cancellationToken ?: CancellationToken
132
150
) : Promise < GetSsoTokenResult > {
133
- return this . client . sendRequest (
151
+ const response : GetSsoTokenResult = await this . client . sendRequest (
134
152
getSsoTokenRequestType . method ,
135
153
{
136
154
clientName : this . clientName ,
@@ -142,14 +160,17 @@ export class LanguageClientAuth {
142
160
} satisfies GetSsoTokenParams ,
143
161
cancellationToken
144
162
)
163
+ // Decrypt the access token
164
+ response . ssoToken . accessToken = await this . decrypt ( response . ssoToken . accessToken )
165
+ return response
145
166
}
146
167
147
- getIamCredential (
168
+ async getIamCredential (
148
169
profileName : string ,
149
170
login : boolean = false ,
150
171
cancellationToken ?: CancellationToken
151
172
) : Promise < GetIamCredentialResult > {
152
- return this . client . sendRequest (
173
+ const response : GetIamCredentialResult = await this . client . sendRequest (
153
174
getIamCredentialRequestType . method ,
154
175
{
155
176
profileName : profileName ,
@@ -159,16 +180,25 @@ export class LanguageClientAuth {
159
180
} satisfies GetIamCredentialParams ,
160
181
cancellationToken
161
182
)
183
+ // Decrypt the response credentials
184
+ const { accessKeyId, secretAccessKey, sessionToken, expiration } = response . credential . credentials
185
+ response . credential . credentials = {
186
+ accessKeyId : await this . decrypt ( accessKeyId ) ,
187
+ secretAccessKey : await this . decrypt ( secretAccessKey ) ,
188
+ sessionToken : sessionToken ? await this . decrypt ( sessionToken ) : undefined ,
189
+ expiration : expiration ,
190
+ }
191
+ return response
162
192
}
163
193
164
- updateSsoProfile (
194
+ async updateSsoProfile (
165
195
profileName : string ,
166
196
startUrl : string ,
167
197
region : string ,
168
198
scopes : string [ ]
169
199
) : Promise < UpdateProfileResult > {
170
200
// Add SSO settings and delete credentials from profile
171
- return this . client . sendRequest ( updateProfileRequestType . method , {
201
+ const params = await this . encrypt ( {
172
202
profile : {
173
203
kinds : [ ProfileKind . SsoTokenProfile ] ,
174
204
name : profileName ,
@@ -188,10 +218,11 @@ export class LanguageClientAuth {
188
218
sso_registration_scopes : scopes ,
189
219
} ,
190
220
} ,
191
- } satisfies UpdateProfileParams )
221
+ } )
222
+ return this . client . sendRequest ( updateProfileRequestType . method , params )
192
223
}
193
224
194
- updateIamProfile ( profileName : string , opts : IamProfileOptions ) : Promise < UpdateProfileResult > {
225
+ async updateIamProfile ( profileName : string , opts : IamProfileOptions ) : Promise < UpdateProfileResult > {
195
226
// Substitute missing fields for defaults
196
227
const fields = { ...IamProfileOptionsDefaults , ...opts }
197
228
// Get the profile kind matching the provided fields
@@ -204,7 +235,7 @@ export class LanguageClientAuth {
204
235
kind = ProfileKind . Unknown
205
236
}
206
237
207
- return this . client . sendRequest ( updateProfileRequestType . method , {
238
+ const params = await this . encrypt ( {
208
239
profile : {
209
240
kinds : [ kind ] ,
210
241
name : profileName ,
@@ -217,10 +248,12 @@ export class LanguageClientAuth {
217
248
} ,
218
249
} ,
219
250
} )
251
+ return this . client . sendRequest ( updateProfileRequestType . method , params )
220
252
}
221
253
222
- listProfiles ( ) {
223
- return this . client . sendRequest ( listProfilesRequestType . method , { } ) as Promise < ListProfilesResult >
254
+ async listProfiles ( ) {
255
+ const response : string = await this . client . sendRequest ( listProfilesRequestType . method , { } )
256
+ return await this . decrypt < ListProfilesResult > ( response )
224
257
}
225
258
226
259
/**
@@ -352,19 +385,6 @@ export abstract class BaseLogin {
352
385
this . eventEmitter . fire ( { id : this . profileName , state : this . connectionState } )
353
386
}
354
387
}
355
-
356
- /**
357
- * Decrypts an encrypted string, removes its quotes, and returns the resulting string
358
- */
359
- protected async decrypt ( encrypted : string ) : Promise < string > {
360
- try {
361
- const decrypted = await jose . compactDecrypt ( encrypted , this . lspAuth . encryptionKey )
362
- return decrypted . plaintext . toString ( ) . replaceAll ( '"' , '' )
363
- } catch ( e ) {
364
- getLogger ( ) . error ( `Failed to decrypt: ${ encrypted } ` )
365
- return encrypted
366
- }
367
- }
368
388
}
369
389
370
390
/**
@@ -436,9 +456,8 @@ export class SsoLogin extends BaseLogin {
436
456
*/
437
457
async getCredential ( ) {
438
458
const response = await this . _getSsoToken ( false )
439
- const accessToken = await this . decrypt ( response . ssoToken . accessToken )
440
459
return {
441
- credential : accessToken ,
460
+ credential : response . ssoToken . accessToken ,
442
461
updateCredentialsParams : response . updateCredentialsParams ,
443
462
}
444
463
}
@@ -562,7 +581,7 @@ export class IamLogin extends BaseLogin {
562
581
sourceProfile : sourceProfile ,
563
582
} )
564
583
} else {
565
- // Create the target profile
584
+ // Create the credentials profile
566
585
await this . lspAuth . updateIamProfile ( this . profileName , {
567
586
accessKey : opts . accessKey ,
568
587
secretKey : opts . secretKey ,
@@ -575,14 +594,6 @@ export class IamLogin extends BaseLogin {
575
594
* Restore the connection state and connection details to memory, if they exist.
576
595
*/
577
596
async restore ( ) {
578
- const sessionData = await this . getProfile ( )
579
- const credentials = sessionData ?. profile ?. settings
580
- if ( credentials ?. aws_access_key_id && credentials ?. aws_secret_access_key ) {
581
- this . _data = {
582
- accessKey : credentials . aws_access_key_id ,
583
- secretKey : credentials . aws_secret_access_key ,
584
- }
585
- }
586
597
try {
587
598
await this . _getIamCredential ( false )
588
599
} catch ( err ) {
@@ -596,15 +607,8 @@ export class IamLogin extends BaseLogin {
596
607
*/
597
608
async getCredential ( ) {
598
609
const response = await this . _getIamCredential ( false )
599
- const credentials : IamCredentials = {
600
- accessKeyId : await this . decrypt ( response . credential . credentials . accessKeyId ) ,
601
- secretAccessKey : await this . decrypt ( response . credential . credentials . secretAccessKey ) ,
602
- sessionToken : response . credential . credentials . sessionToken
603
- ? await this . decrypt ( response . credential . credentials . sessionToken )
604
- : undefined ,
605
- }
606
610
return {
607
- credential : credentials ,
611
+ credential : response . credential . credentials ,
608
612
updateCredentialsParams : response . updateCredentialsParams ,
609
613
}
610
614
}
@@ -639,7 +643,7 @@ export class IamLogin extends BaseLogin {
639
643
}
640
644
641
645
// Update cached credentials and credential ID
642
- if ( response . credential ? .credentials ? .accessKeyId && response . credential ? .credentials ? .secretAccessKey ) {
646
+ if ( response . credential . credentials . accessKeyId && response . credential . credentials . secretAccessKey ) {
643
647
this . _data = {
644
648
accessKey : response . credential . credentials . accessKeyId ,
645
649
secretKey : response . credential . credentials . secretAccessKey ,
0 commit comments