@@ -8,17 +8,19 @@ import Instance from "./api/Instance";
88import { Search } from "./api/Search" ;
99import { Terminal } from './api/Terminal' ;
1010import { refreshDiagnosticsFromServer } from './api/errors/diagnostics' ;
11+ import { setupGitEventHandler } from './api/local/git' ;
1112import { QSysFS , getUriFromPath , parseFSOptions } from "./filesystems/qsys/QSysFs" ;
1213import { initGetNewLibl } from "./languages/clle/getnewlibl" ;
1314import { SEUColorProvider } from "./languages/general/SEUColorProvider" ;
1415import { Action , BrowserItem , DeploymentMethod , MemberItem , OpenEditableOptions , WithPath } from "./typings" ;
1516import { SearchView } from "./views/searchView" ;
1617import { ActionsUI } from './webviews/actions' ;
1718import { VariablesUI } from "./webviews/variables" ;
18- import { setupGitEventHandler } from './api/local/git' ;
1919
2020export let instance : Instance ;
2121
22+ const passwordAttempts : { [ extensionId : string ] : number } = { }
23+
2224const CLEAR_RECENT = `$(trash) Clear recently opened` ;
2325const CLEAR_CACHED = `$(trash) Clear cached` ;
2426
@@ -618,14 +620,82 @@ export async function loadAllofExtension(context: vscode.ExtensionContext) {
618620 }
619621 } ) ,
620622
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 ) ;
627641
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+ }
629699 } ) ,
630700
631701 vscode . commands . registerCommand ( "code-for-ibmi.browse" , ( item : WithPath | MemberItem ) => {
@@ -660,7 +730,7 @@ export async function loadAllofExtension(context: vscode.ExtensionContext) {
660730 }
661731
662732 // Register git events based on workspace folders
663- if ( vscode . workspace . workspaceFolders ) {
733+ if ( vscode . workspace . workspaceFolders ) {
664734 setupGitEventHandler ( context ) ;
665735 }
666736
0 commit comments