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

Commit53432cb

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

File tree

2 files changed

+73
-40
lines changed

2 files changed

+73
-40
lines changed

‎src/extension.ts‎

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,15 @@ export async function activate(ctx: vscode.ExtensionContext): Promise<void> {
309309
commands.viewLogs.bind(commands),
310310
);
311311

312+
constremote=newRemote(
313+
vscodeProposed,
314+
output,
315+
commands,
316+
ctx.extensionMode,
317+
pathResolver,
318+
cliManager,
319+
);
320+
312321
ctx.subscriptions.push(
313322
secretsManager.onDidChangeSessionToken(async()=>{
314323
consttoken=awaitsecretsManager.getSessionToken();
@@ -320,6 +329,8 @@ export async function activate(ctx: vscode.ExtensionContext): Promise<void> {
320329
output.info("Logging in");
321330
// Should login the user directly if the URL+Token are valid
322331
awaitcommands.login({ url, token});
332+
// Resolve any pending login detection promises
333+
remote.resolveLoginDetected();
323334
}
324335
}),
325336
);
@@ -334,14 +345,6 @@ export async function activate(ctx: vscode.ExtensionContext): Promise<void> {
334345
// (this would require the user to uninstall the Coder extension and
335346
// reinstall after installing the remote SSH extension, which is annoying)
336347
if(remoteSSHExtension&&vscodeProposed.env.remoteAuthority){
337-
constremote=newRemote(
338-
vscodeProposed,
339-
output,
340-
commands,
341-
ctx.extensionMode,
342-
pathResolver,
343-
cliManager,
344-
);
345348
try{
346349
constdetails=awaitremote.setup(
347350
vscodeProposed.env.remoteAuthority,

‎src/remote.ts‎

Lines changed: 62 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ export interface RemoteDetails extends vscode.Disposable {
4444
}
4545

4646
exportclassRemote{
47+
privateloginDetectedResolver:(()=>void)|undefined;
48+
privateloginDetectedPromise:Promise<void>=Promise.resolve();
49+
4750
publicconstructor(
4851
// We use the proposed API to get access to useCustom in dialogs.
4952
privatereadonlyvscodeProposed:typeofvscode,
@@ -54,6 +57,27 @@ export class Remote {
5457
privatereadonlycliManager:CliManager,
5558
){}
5659

60+
/**
61+
* Creates a new promise that will be resolved when login is detected in another window.
62+
* This should be called when starting a setup operation that might need login.
63+
*/
64+
privatecreateLoginDetectionPromise():void{
65+
this.loginDetectedPromise=newPromise<void>((resolve)=>{
66+
this.loginDetectedResolver=resolve;
67+
});
68+
}
69+
70+
/**
71+
* Resolves the current login detection promise if one exists.
72+
* This should be called from the extension when login is detected.
73+
*/
74+
publicresolveLoginDetected():void{
75+
if(this.loginDetectedResolver){
76+
this.loginDetectedResolver();
77+
this.loginDetectedResolver=undefined;
78+
}
79+
}
80+
5781
privateasyncconfirmStart(workspaceName:string):Promise<boolean>{
5882
constaction=awaitthis.vscodeProposed.window.showInformationMessage(
5983
`Unable to connect to the workspace${workspaceName} because it is not running. Start the workspace?`,
@@ -217,34 +241,54 @@ export class Remote {
217241
// Migrate "session_token" file to "session", if needed.
218242
awaitthis.migrateSessionToken(parts.label);
219243

244+
// Try to detect any login event that might happen after we read the current configs
245+
this.createLoginDetectionPromise();
220246
// Get the URL and token belonging to this host.
221247
const{url:baseUrlRaw, token}=awaitthis.cliManager.readConfig(
222248
parts.label,
223249
);
224250

225-
// It could be that the cli config was deleted. If so, ask for the url.
226-
if(
227-
!baseUrlRaw||
228-
(!token&&needToken(vscode.workspace.getConfiguration()))
229-
){
230-
constresult=awaitthis.vscodeProposed.window.showInformationMessage(
231-
"You are not logged in...",
251+
constshowLoginDialog=async(message:string)=>{
252+
constdialogPromise=this.vscodeProposed.window.showInformationMessage(
253+
message,
232254
{
233255
useCustom:true,
234256
modal:true,
235-
detail:`You must log in to access${workspaceName}.`,
257+
detail:`You must log in to access${workspaceName}. If you've already logged in, you may close this dialog.`,
236258
},
237259
"Log In",
238260
);
239-
if(!result){
240-
// User declined to log in.
241-
awaitthis.closeRemote();
261+
262+
// Race between dialog and login detection
263+
constresult=awaitPromise.race([
264+
this.loginDetectedPromise.then(()=>({type:"login"asconst})),
265+
dialogPromise.then((userChoice)=>({
266+
type:"dialog"asconst,
267+
userChoice,
268+
})),
269+
]);
270+
271+
if(result.type==="login"){
272+
returnthis.setup(remoteAuthority,firstConnect);
242273
}else{
243-
// Log in then try again.
244-
awaitthis.commands.login({url:baseUrlRaw,label:parts.label});
245-
awaitthis.setup(remoteAuthority,firstConnect);
274+
if(!result.userChoice){
275+
// User declined to log in.
276+
awaitthis.closeRemote();
277+
return;
278+
}else{
279+
// Log in then try again.
280+
awaitthis.commands.login({url:baseUrlRaw,label:parts.label});
281+
returnthis.setup(remoteAuthority,firstConnect);
282+
}
246283
}
247-
return;
284+
};
285+
286+
// It could be that the cli config was deleted. If so, ask for the url.
287+
if(
288+
!baseUrlRaw||
289+
(!token&&needToken(vscode.workspace.getConfiguration()))
290+
){
291+
returnshowLoginDialog("You are not logged in...");
248292
}
249293

250294
this.logger.info("Using deployment URL",baseUrlRaw);
@@ -315,6 +359,8 @@ export class Remote {
315359
// Next is to find the workspace from the URI scheme provided.
316360
letworkspace:Workspace;
317361
try{
362+
// We could've logged out in the meantime
363+
this.createLoginDetectionPromise();
318364
this.logger.info(`Looking for workspace${workspaceName}...`);
319365
workspace=awaitworkspaceClient.getWorkspaceByOwnerAndName(
320366
parts.username,
@@ -348,23 +394,7 @@ export class Remote {
348394
return;
349395
}
350396
case401:{
351-
constresult=
352-
awaitthis.vscodeProposed.window.showInformationMessage(
353-
"Your session expired...",
354-
{
355-
useCustom:true,
356-
modal:true,
357-
detail:`You must log in to access${workspaceName}.`,
358-
},
359-
"Log In",
360-
);
361-
if(!result){
362-
awaitthis.closeRemote();
363-
}else{
364-
awaitthis.commands.login({url:baseUrlRaw,label:parts.label});
365-
awaitthis.setup(remoteAuthority,firstConnect);
366-
}
367-
return;
397+
returnshowLoginDialog("Your session expired...");
368398
}
369399
default:
370400
throwerror;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp