Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitdf63df6

Browse files
committed
Add a race between login event and dialog promise when connecting and logged out
1 parentf933177 commitdf63df6

File tree

2 files changed

+66
-33
lines changed

2 files changed

+66
-33
lines changed

‎src/extension.ts‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,8 @@ export async function activate(ctx: vscode.ExtensionContext): Promise<void> {
327327
),
328328
);
329329

330+
constremote=newRemote(serviceContainer,commands,ctx.extensionMode);
331+
330332
ctx.subscriptions.push(
331333
secretsManager.onDidChangeSessionToken(async()=>{
332334
consttoken=awaitsecretsManager.getSessionToken();
@@ -338,6 +340,8 @@ export async function activate(ctx: vscode.ExtensionContext): Promise<void> {
338340
output.info("Logging in");
339341
// Should login the user directly if the URL+Token are valid
340342
awaitcommands.login({ url, token});
343+
// Resolve any pending login detection promises
344+
remote.resolveLoginDetected();
341345
}
342346
}),
343347
);
@@ -352,7 +356,6 @@ export async function activate(ctx: vscode.ExtensionContext): Promise<void> {
352356
// (this would require the user to uninstall the Coder extension and
353357
// reinstall after installing the remote SSH extension, which is annoying)
354358
if(remoteSSHExtension&&vscodeProposed.env.remoteAuthority){
355-
constremote=newRemote(serviceContainer,commands,ctx.extensionMode);
356359
try{
357360
constdetails=awaitremote.setup(
358361
vscodeProposed.env.remoteAuthority,

‎src/remote/remote.ts‎

Lines changed: 62 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ export class Remote {
5959
privatereadonlypathResolver:PathResolver;
6060
privatereadonlycliManager:CliManager;
6161

62+
privateloginDetectedResolver:(()=>void)|undefined;
63+
privateloginDetectedPromise:Promise<void>=Promise.resolve();
64+
6265
publicconstructor(
6366
serviceContainer:ServiceContainer,
6467
privatereadonlycommands:Commands,
@@ -70,6 +73,27 @@ export class Remote {
7073
this.cliManager=serviceContainer.getCliManager();
7174
}
7275

76+
/**
77+
* Creates a new promise that will be resolved when login is detected in another window.
78+
* This should be called when starting a setup operation that might need login.
79+
*/
80+
privatecreateLoginDetectionPromise():void{
81+
this.loginDetectedPromise=newPromise<void>((resolve)=>{
82+
this.loginDetectedResolver=resolve;
83+
});
84+
}
85+
86+
/**
87+
* Resolves the current login detection promise if one exists.
88+
* This should be called from the extension when login is detected.
89+
*/
90+
publicresolveLoginDetected():void{
91+
if(this.loginDetectedResolver){
92+
this.loginDetectedResolver();
93+
this.loginDetectedResolver=undefined;
94+
}
95+
}
96+
7397
privateasyncconfirmStart(workspaceName:string):Promise<boolean>{
7498
constaction=awaitthis.vscodeProposed.window.showInformationMessage(
7599
`Unable to connect to the workspace${workspaceName} because it is not running. Start the workspace?`,
@@ -233,34 +257,54 @@ export class Remote {
233257
// Migrate "session_token" file to "session", if needed.
234258
awaitthis.migrateSessionToken(parts.label);
235259

260+
// Try to detect any login event that might happen after we read the current configs
261+
this.createLoginDetectionPromise();
236262
// Get the URL and token belonging to this host.
237263
const{url:baseUrlRaw, token}=awaitthis.cliManager.readConfig(
238264
parts.label,
239265
);
240266

241-
// It could be that the cli config was deleted. If so, ask for the url.
242-
if(
243-
!baseUrlRaw||
244-
(!token&&needToken(vscode.workspace.getConfiguration()))
245-
){
246-
constresult=awaitthis.vscodeProposed.window.showInformationMessage(
247-
"You are not logged in...",
267+
constshowLoginDialog=async(message:string)=>{
268+
constdialogPromise=this.vscodeProposed.window.showInformationMessage(
269+
message,
248270
{
249271
useCustom:true,
250272
modal:true,
251-
detail:`You must log in to access${workspaceName}.`,
273+
detail:`You must log in to access${workspaceName}. If you've already logged in, you may close this dialog.`,
252274
},
253275
"Log In",
254276
);
255-
if(!result){
256-
// User declined to log in.
257-
awaitthis.closeRemote();
277+
278+
// Race between dialog and login detection
279+
constresult=awaitPromise.race([
280+
this.loginDetectedPromise.then(()=>({type:"login"asconst})),
281+
dialogPromise.then((userChoice)=>({
282+
type:"dialog"asconst,
283+
userChoice,
284+
})),
285+
]);
286+
287+
if(result.type==="login"){
288+
returnthis.setup(remoteAuthority,firstConnect);
258289
}else{
259-
// Log in then try again.
260-
awaitthis.commands.login({url:baseUrlRaw,label:parts.label});
261-
awaitthis.setup(remoteAuthority,firstConnect);
290+
if(!result.userChoice){
291+
// User declined to log in.
292+
awaitthis.closeRemote();
293+
return;
294+
}else{
295+
// Log in then try again.
296+
awaitthis.commands.login({url:baseUrlRaw,label:parts.label});
297+
returnthis.setup(remoteAuthority,firstConnect);
298+
}
262299
}
263-
return;
300+
};
301+
302+
// It could be that the cli config was deleted. If so, ask for the url.
303+
if(
304+
!baseUrlRaw||
305+
(!token&&needToken(vscode.workspace.getConfiguration()))
306+
){
307+
returnshowLoginDialog("You are not logged in...");
264308
}
265309

266310
this.logger.info("Using deployment URL",baseUrlRaw);
@@ -326,6 +370,8 @@ export class Remote {
326370
// Next is to find the workspace from the URI scheme provided.
327371
letworkspace:Workspace;
328372
try{
373+
// We could've logged out in the meantime
374+
this.createLoginDetectionPromise();
329375
this.logger.info(`Looking for workspace${workspaceName}...`);
330376
workspace=awaitworkspaceClient.getWorkspaceByOwnerAndName(
331377
parts.username,
@@ -359,23 +405,7 @@ export class Remote {
359405
return;
360406
}
361407
case401:{
362-
constresult=
363-
awaitthis.vscodeProposed.window.showInformationMessage(
364-
"Your session expired...",
365-
{
366-
useCustom:true,
367-
modal:true,
368-
detail:`You must log in to access${workspaceName}.`,
369-
},
370-
"Log In",
371-
);
372-
if(!result){
373-
awaitthis.closeRemote();
374-
}else{
375-
awaitthis.commands.login({url:baseUrlRaw,label:parts.label});
376-
awaitthis.setup(remoteAuthority,firstConnect);
377-
}
378-
return;
408+
returnshowLoginDialog("Your session expired...");
379409
}
380410
default:
381411
throwerror;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp