@@ -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,36 @@ 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
+ try {
143
+ const result = await jose . compactDecrypt ( request , this . encryptionKey )
144
+ return JSON . parse ( new TextDecoder ( ) . decode ( result . plaintext ) ) as T
145
+ } catch ( e ) {
146
+ getLogger ( ) . error ( `Failed to decrypt: ${ request } ` )
147
+ return request as T
148
+ }
149
+ }
150
+
151
+ async getSsoToken (
129
152
tokenSource : TokenSource ,
130
153
login : boolean = false ,
131
154
cancellationToken ?: CancellationToken
132
155
) : Promise < GetSsoTokenResult > {
133
- return this . client . sendRequest (
156
+ const response : GetSsoTokenResult = await this . client . sendRequest (
134
157
getSsoTokenRequestType . method ,
135
158
{
136
159
clientName : this . clientName ,
@@ -142,14 +165,17 @@ export class LanguageClientAuth {
142
165
} satisfies GetSsoTokenParams ,
143
166
cancellationToken
144
167
)
168
+ // Decrypt the access token
169
+ response . ssoToken . accessToken = await this . decrypt ( response . ssoToken . accessToken )
170
+ return response
145
171
}
146
172
147
- getIamCredential (
173
+ async getIamCredential (
148
174
profileName : string ,
149
175
login : boolean = false ,
150
176
cancellationToken ?: CancellationToken
151
177
) : Promise < GetIamCredentialResult > {
152
- return this . client . sendRequest (
178
+ const response : GetIamCredentialResult = await this . client . sendRequest (
153
179
getIamCredentialRequestType . method ,
154
180
{
155
181
profileName : profileName ,
@@ -159,16 +185,25 @@ export class LanguageClientAuth {
159
185
} satisfies GetIamCredentialParams ,
160
186
cancellationToken
161
187
)
188
+ // Decrypt the response credentials
189
+ const { accessKeyId, secretAccessKey, sessionToken, expiration } = response . credential . credentials
190
+ response . credential . credentials = {
191
+ accessKeyId : await this . decrypt ( accessKeyId ) ,
192
+ secretAccessKey : await this . decrypt ( secretAccessKey ) ,
193
+ sessionToken : sessionToken ? await this . decrypt ( sessionToken ) : undefined ,
194
+ expiration : expiration ,
195
+ }
196
+ return response
162
197
}
163
198
164
- updateSsoProfile (
199
+ async updateSsoProfile (
165
200
profileName : string ,
166
201
startUrl : string ,
167
202
region : string ,
168
203
scopes : string [ ]
169
204
) : Promise < UpdateProfileResult > {
170
205
// Add SSO settings and delete credentials from profile
171
- return this . client . sendRequest ( updateProfileRequestType . method , {
206
+ const params = await this . encrypt ( {
172
207
profile : {
173
208
kinds : [ ProfileKind . SsoTokenProfile ] ,
174
209
name : profileName ,
@@ -188,10 +223,11 @@ export class LanguageClientAuth {
188
223
sso_registration_scopes : scopes ,
189
224
} ,
190
225
} ,
191
- } satisfies UpdateProfileParams )
226
+ } )
227
+ return this . client . sendRequest ( updateProfileRequestType . method , params )
192
228
}
193
229
194
- updateIamProfile ( profileName : string , opts : IamProfileOptions ) : Promise < UpdateProfileResult > {
230
+ async updateIamProfile ( profileName : string , opts : IamProfileOptions ) : Promise < UpdateProfileResult > {
195
231
// Substitute missing fields for defaults
196
232
const fields = { ...IamProfileOptionsDefaults , ...opts }
197
233
// Get the profile kind matching the provided fields
@@ -204,7 +240,7 @@ export class LanguageClientAuth {
204
240
kind = ProfileKind . Unknown
205
241
}
206
242
207
- return this . client . sendRequest ( updateProfileRequestType . method , {
243
+ const params = await this . encrypt ( {
208
244
profile : {
209
245
kinds : [ kind ] ,
210
246
name : profileName ,
@@ -217,10 +253,12 @@ export class LanguageClientAuth {
217
253
} ,
218
254
} ,
219
255
} )
256
+ return this . client . sendRequest ( updateProfileRequestType . method , params )
220
257
}
221
258
222
- listProfiles ( ) {
223
- return this . client . sendRequest ( listProfilesRequestType . method , { } ) as Promise < ListProfilesResult >
259
+ async listProfiles ( ) {
260
+ const response : string = await this . client . sendRequest ( listProfilesRequestType . method , { } )
261
+ return await this . decrypt < ListProfilesResult > ( response )
224
262
}
225
263
226
264
/**
@@ -352,19 +390,6 @@ export abstract class BaseLogin {
352
390
this . eventEmitter . fire ( { id : this . profileName , state : this . connectionState } )
353
391
}
354
392
}
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
393
}
369
394
370
395
/**
@@ -436,9 +461,8 @@ export class SsoLogin extends BaseLogin {
436
461
*/
437
462
async getCredential ( ) {
438
463
const response = await this . _getSsoToken ( false )
439
- const accessToken = await this . decrypt ( response . ssoToken . accessToken )
440
464
return {
441
- credential : accessToken ,
465
+ credential : response . ssoToken . accessToken ,
442
466
updateCredentialsParams : response . updateCredentialsParams ,
443
467
}
444
468
}
@@ -562,7 +586,7 @@ export class IamLogin extends BaseLogin {
562
586
sourceProfile : sourceProfile ,
563
587
} )
564
588
} else {
565
- // Create the target profile
589
+ // Create the credentials profile
566
590
await this . lspAuth . updateIamProfile ( this . profileName , {
567
591
accessKey : opts . accessKey ,
568
592
secretKey : opts . secretKey ,
@@ -575,14 +599,6 @@ export class IamLogin extends BaseLogin {
575
599
* Restore the connection state and connection details to memory, if they exist.
576
600
*/
577
601
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
602
try {
587
603
await this . _getIamCredential ( false )
588
604
} catch ( err ) {
@@ -596,15 +612,8 @@ export class IamLogin extends BaseLogin {
596
612
*/
597
613
async getCredential ( ) {
598
614
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
615
return {
607
- credential : credentials ,
616
+ credential : response . credential . credentials ,
608
617
updateCredentialsParams : response . updateCredentialsParams ,
609
618
}
610
619
}
@@ -639,7 +648,7 @@ export class IamLogin extends BaseLogin {
639
648
}
640
649
641
650
// Update cached credentials and credential ID
642
- if ( response . credential ? .credentials ? .accessKeyId && response . credential ? .credentials ? .secretAccessKey ) {
651
+ if ( response . credential . credentials . accessKeyId && response . credential . credentials . secretAccessKey ) {
643
652
this . _data = {
644
653
accessKey : response . credential . credentials . accessKeyId ,
645
654
secretKey : response . credential . credentials . secretAccessKey ,
0 commit comments