@@ -6,7 +6,7 @@ import { EventEmitter } from "events";
66import * as vscode from "vscode" ;
77import { leetCodeChannel } from "./leetCodeChannel" ;
88import { leetCodeExecutor } from "./leetCodeExecutor" ;
9- import { UserStatus } from "./shared" ;
9+ import { IQuickItemEx , loginArgsMapping , UserStatus } from "./shared" ;
1010import { createEnvOption } from "./utils/cpUtils" ;
1111import { DialogType , promptForOpenOutputChannel } from "./utils/uiUtils" ;
1212import * as wsl from "./utils/wslUtils" ;
@@ -34,14 +34,43 @@ class LeetCodeManager extends EventEmitter {
3434 }
3535 }
3636
37- public async signIn ( isByCookie : boolean = false ) : Promise < void > {
38- const loginArg : string = "-l" ;
39- const cookieArg : string = "-c" ;
40- const commandArg : string = isByCookie ? cookieArg : loginArg ;
37+ public async signIn ( ) : Promise < void > {
38+ const picks : Array < IQuickItemEx < string > > = [ ] ;
39+ picks . push (
40+ {
41+ label : "LeetCode Account" ,
42+ detail : "Use LeetCode account to login" ,
43+ value : "LeetCode" ,
44+ } ,
45+ {
46+ label : "LeetCode Cookie" ,
47+ detail : "Use LeetCode cookie copied from browser to login" ,
48+ value : "Cookie" ,
49+ } ,
50+ {
51+ label : "Third-Party: GitHub" ,
52+ detail : "Use GitHub account to login" ,
53+ value : "GitHub" ,
54+ } ,
55+ {
56+ label : "Third-Party: LinkedIn" ,
57+ detail : "Use LinkedIn account to login" ,
58+ value : "LinkedIn" ,
59+ } ,
60+ ) ;
61+ const choice : IQuickItemEx < string > | undefined = await vscode . window . showQuickPick ( picks ) ;
62+ if ( ! choice ) {
63+ return ;
64+ }
65+ const loginMethod : string = choice . value ;
66+ const commandArg : string | undefined = loginArgsMapping . get ( loginMethod ) ;
67+ if ( ! commandArg ) {
68+ throw new Error ( `The login method "${ loginMethod } " is not supported.` ) ;
69+ }
70+ const isByCookie : boolean = loginMethod === "Cookie" ;
4171 const inMessage : string = isByCookie ? "sign in by cookie" : "sign in" ;
4272 try {
4373 const userName : string | undefined = await new Promise ( async ( resolve : ( res : string | undefined ) => void , reject : ( e : Error ) => void ) : Promise < void > => {
44- let result : string = "" ;
4574
4675 const leetCodeBinaryPath : string = await leetCodeExecutor . getLeetCodeBinaryPath ( ) ;
4776
@@ -52,10 +81,27 @@ class LeetCodeManager extends EventEmitter {
5281 env : createEnvOption ( ) ,
5382 } ) ;
5483
55- childProc . stdout . on ( "data" , ( data : string | Buffer ) => {
84+ childProc . stdout . on ( "data" , async ( data : string | Buffer ) => {
5685 data = data . toString ( ) ;
57- result = result . concat ( data ) ;
5886 leetCodeChannel . append ( data ) ;
87+ if ( data . includes ( "twoFactorCode" ) ) {
88+ const twoFactor : string | undefined = await vscode . window . showInputBox ( {
89+ prompt : "Enter two-factor code." ,
90+ validateInput : ( s : string ) : string | undefined => s && s . trim ( ) ? undefined : "The input must not be empty" ,
91+ } ) ;
92+ if ( ! twoFactor ) {
93+ childProc . kill ( ) ;
94+ return resolve ( undefined ) ;
95+ }
96+ childProc . stdin . write ( `${ twoFactor } \n` ) ;
97+ childProc . stdin . end ( ) ;
98+ } else {
99+ const match : RegExpMatchArray | null = data . match ( / (?: .* ) S u c c e s s f u l l y .* l o g i n a s ( .* ) / i) ;
100+ if ( match && match [ 1 ] ) {
101+ childProc . stdin . end ( ) ;
102+ return resolve ( match [ 1 ] ) ;
103+ }
104+ }
59105 } ) ;
60106
61107 childProc . stderr . on ( "data" , ( data : string | Buffer ) => leetCodeChannel . append ( data . toString ( ) ) ) ;
@@ -80,13 +126,9 @@ class LeetCodeManager extends EventEmitter {
80126 return resolve ( undefined ) ;
81127 }
82128 childProc . stdin . write ( `${ pwd } \n` ) ;
83- childProc . stdin . end ( ) ;
84- childProc . on ( "close" , ( ) => {
85- const match : RegExpMatchArray | null = result . match ( / (?: .* ) S u c c e s s f u l l y ( l o g i n | c o o k i e l o g i n ) a s ( .* ) / i) ;
86- if ( match && match [ 2 ] ) {
87- resolve ( match [ 2 ] ) ;
88- } else {
89- reject ( new Error ( `Failed to ${ inMessage } .` ) ) ;
129+ childProc . on ( "close" , ( code : number ) => {
130+ if ( code !== 0 ) {
131+ reject ( new Error ( "Failed to login." ) ) ;
90132 }
91133 } ) ;
92134 } ) ;
0 commit comments