@@ -8,17 +8,19 @@ import Instance from "./api/Instance";
8
8
import { Search } from "./api/Search" ;
9
9
import { Terminal } from './api/Terminal' ;
10
10
import { refreshDiagnosticsFromServer } from './api/errors/diagnostics' ;
11
+ import { setupGitEventHandler } from './api/local/git' ;
11
12
import { QSysFS , getUriFromPath , parseFSOptions } from "./filesystems/qsys/QSysFs" ;
12
13
import { initGetNewLibl } from "./languages/clle/getnewlibl" ;
13
14
import { SEUColorProvider } from "./languages/general/SEUColorProvider" ;
14
15
import { Action , BrowserItem , DeploymentMethod , MemberItem , OpenEditableOptions , WithPath } from "./typings" ;
15
16
import { SearchView } from "./views/searchView" ;
16
17
import { ActionsUI } from './webviews/actions' ;
17
18
import { VariablesUI } from "./webviews/variables" ;
18
- import { setupGitEventHandler } from './api/local/git' ;
19
19
20
20
export let instance : Instance ;
21
21
22
+ const passwordAttempts : { [ extensionId : string ] : number } = { }
23
+
22
24
const CLEAR_RECENT = `$(trash) Clear recently opened` ;
23
25
const CLEAR_CACHED = `$(trash) Clear cached` ;
24
26
@@ -618,14 +620,82 @@ export async function loadAllofExtension(context: vscode.ExtensionContext) {
618
620
}
619
621
} ) ,
620
622
621
- vscode . commands . registerCommand ( `code-for-ibmi.secret` , async ( key : string , newValue : string ) => {
622
- const connectionKey = `${ instance . getConnection ( ) ! . currentConnectionName } _${ key } ` ;
623
- if ( newValue ) {
624
- await context . secrets . store ( connectionKey , newValue ) ;
625
- return newValue ;
626
- }
623
+ vscode . commands . registerCommand ( `code-for-ibmi.getPassword` , async ( extensionId : string , reason ?: string ) => {
624
+ if ( extensionId ) {
625
+ const extension = vscode . extensions . getExtension ( extensionId ) ;
626
+ const isValid = ( extension && extension . isActive ) ;
627
+ if ( isValid ) {
628
+ const connection = instance . getConnection ( ) ;
629
+ const storage = instance . getStorage ( ) ;
630
+ if ( connection && storage ) {
631
+ const displayName = extension . packageJSON . displayName || extensionId ;
632
+
633
+ // Some logic to stop spam from extensions.
634
+ passwordAttempts [ extensionId ] = passwordAttempts [ extensionId ] || 0 ;
635
+ if ( passwordAttempts [ extensionId ] > 1 ) {
636
+ throw new Error ( `Password request denied for extension ${ displayName } .` ) ;
637
+ }
638
+
639
+ const connectionKey = `${ instance . getConnection ( ) ! . currentConnectionName } _password` ;
640
+ const storedPassword = await context . secrets . get ( connectionKey ) ;
627
641
628
- return await context . secrets . get ( connectionKey ) ;
642
+ if ( storedPassword ) {
643
+ let isAuthed = storage . getExtensionAuthorisation ( extension ) !== undefined ;
644
+
645
+ if ( ! isAuthed ) {
646
+ const detail = `The ${ displayName } extension is requesting access to your password for this connection. ${ reason ? `\n\nReason: ${ reason } ` : `The extension did not provide a reason for password access.` } ` ;
647
+ let done = false ;
648
+ let modal = true ;
649
+
650
+ while ( ! done ) {
651
+ const options : string [ ] = [ `Allow` ] ;
652
+
653
+ if ( modal ) {
654
+ options . push ( `View on Marketplace` ) ;
655
+ } else {
656
+ options . push ( `Deny` ) ;
657
+ }
658
+
659
+ const result = await vscode . window . showWarningMessage (
660
+ modal ? `Password Request` : detail ,
661
+ {
662
+ modal,
663
+ detail,
664
+ } ,
665
+ ...options
666
+ ) ;
667
+
668
+ switch ( result ) {
669
+ case `Allow` :
670
+ await storage . grantExtensionAuthorisation ( extension ) ;
671
+ isAuthed = true ;
672
+ done = true ;
673
+ break ;
674
+
675
+ case `View on Marketplace` :
676
+ vscode . commands . executeCommand ( 'extension.open' , extensionId ) ;
677
+ modal = false ;
678
+ break ;
679
+
680
+ default :
681
+ done = true ;
682
+ break ;
683
+ }
684
+ }
685
+ }
686
+
687
+ if ( isAuthed ) {
688
+ return storedPassword ;
689
+ } else {
690
+ passwordAttempts [ extensionId ] ++ ;
691
+ }
692
+ }
693
+
694
+ } else {
695
+ throw new Error ( `Not connected to an IBM i.` ) ;
696
+ }
697
+ }
698
+ }
629
699
} ) ,
630
700
631
701
vscode . commands . registerCommand ( "code-for-ibmi.browse" , ( item : WithPath | MemberItem ) => {
@@ -660,7 +730,7 @@ export async function loadAllofExtension(context: vscode.ExtensionContext) {
660
730
}
661
731
662
732
// Register git events based on workspace folders
663
- if ( vscode . workspace . workspaceFolders ) {
733
+ if ( vscode . workspace . workspaceFolders ) {
664
734
setupGitEventHandler ( context ) ;
665
735
}
666
736
0 commit comments