diff --git a/README.md b/README.md index b8aac1e3..1d8d21f3 100644 --- a/README.md +++ b/README.md @@ -51,11 +51,9 @@ Thanks for [@yihong0618](https://github.com/yihong0618) provided a workaround wh - Simply click `Sign in to LeetCode` in the `LeetCode Explorer` will let you **sign in** with your LeetCode account. -- You can also use the following command to sign in/sign in (by cookie)/out: +- You can also use the following command to sign in/out: - **LeetCode: Sign in** - - **LeetCode: Sign in (by cookie)** - **LeetCode: Sign out** - --- ### Switch Endpoint diff --git a/docs/README_zh-CN.md b/docs/README_zh-CN.md index 81c98fe7..23faf30c 100644 --- a/docs/README_zh-CN.md +++ b/docs/README_zh-CN.md @@ -53,9 +53,7 @@ - 你也可以使用下来命令登入或利用cookie登入或登出: - **LeetCode: Sign in** - - **LeetCode: Sign in (by cookie)** - **LeetCode: Sign out** - --- ### 切换 LeetCode 版本 diff --git a/package.json b/package.json index 23ab4685..743b2803 100644 --- a/package.json +++ b/package.json @@ -38,17 +38,11 @@ "onCommand:leetcode.testSolution", "onCommand:leetcode.submitSolution", "onCommand:leetcode.switchDefaultLanguage", - "onCommand:leetcode.signinByCookie", "onView:leetCodeExplorer" ], "main": "./out/src/extension", "contributes": { "commands": [ - { - "command": "leetcode.signinByCookie", - "title": "Sign In by Cookie", - "category": "LeetCode" - }, { "command": "leetcode.deleteCache", "title": "Delete Cache", @@ -689,6 +683,6 @@ "markdown-it": "^8.4.2", "require-from-string": "^2.0.2", "unescape-js": "^1.1.1", - "vsc-leetcode-cli": "2.6.19" + "vsc-leetcode-cli": "2.6.20" } } diff --git a/src/extension.ts b/src/extension.ts index 45de4a70..9bb3ad41 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -51,7 +51,6 @@ export async function activate(context: vscode.ExtensionContext): Promise vscode.commands.registerCommand("leetcode.deleteCache", () => cache.deleteCache()), vscode.commands.registerCommand("leetcode.toggleLeetCodeCn", () => plugin.switchEndpoint()), vscode.commands.registerCommand("leetcode.signin", () => leetCodeManager.signIn()), - vscode.commands.registerCommand("leetcode.signinByCookie", () => leetCodeManager.signIn(true)), vscode.commands.registerCommand("leetcode.signout", () => leetCodeManager.signOut()), vscode.commands.registerCommand("leetcode.manageSessions", () => session.manageSessions()), vscode.commands.registerCommand("leetcode.previewProblem", (node: LeetCodeNode) => show.previewProblem(node)), diff --git a/src/leetCodeManager.ts b/src/leetCodeManager.ts index 0b70080e..25439048 100644 --- a/src/leetCodeManager.ts +++ b/src/leetCodeManager.ts @@ -6,7 +6,7 @@ import { EventEmitter } from "events"; import * as vscode from "vscode"; import { leetCodeChannel } from "./leetCodeChannel"; import { leetCodeExecutor } from "./leetCodeExecutor"; -import { UserStatus } from "./shared"; +import { IQuickItemEx, loginArgsMapping, UserStatus } from "./shared"; import { createEnvOption } from "./utils/cpUtils"; import { DialogType, promptForOpenOutputChannel } from "./utils/uiUtils"; import * as wsl from "./utils/wslUtils"; @@ -34,14 +34,43 @@ class LeetCodeManager extends EventEmitter { } } - public async signIn(isByCookie: boolean = false): Promise { - const loginArg: string = "-l"; - const cookieArg: string = "-c"; - const commandArg: string = isByCookie ? cookieArg : loginArg; + public async signIn(): Promise { + const picks: Array> = []; + picks.push( + { + label: "LeetCode Account", + detail: "Use LeetCode account to login", + value: "LeetCode", + }, + { + label: "LeetCode Cookie", + detail: "Use LeetCode cookie copied from browser to login", + value: "Cookie", + }, + { + label: "Third-Party: GitHub", + detail: "Use GitHub account to login", + value: "GitHub", + }, + { + label: "Third-Party: LinkedIn", + detail: "Use LinkedIn account to login", + value: "LinkedIn", + }, + ); + const choice: IQuickItemEx | undefined = await vscode.window.showQuickPick(picks); + if (!choice) { + return; + } + const loginMethod: string = choice.value; + const commandArg: string | undefined = loginArgsMapping.get(loginMethod); + if (!commandArg) { + throw new Error(`The login method "${loginMethod}" is not supported.`); + } + const isByCookie: boolean = loginMethod === "Cookie"; const inMessage: string = isByCookie ? "sign in by cookie" : "sign in"; try { const userName: string | undefined = await new Promise(async (resolve: (res: string | undefined) => void, reject: (e: Error) => void): Promise => { - let result: string = ""; const leetCodeBinaryPath: string = await leetCodeExecutor.getLeetCodeBinaryPath(); @@ -52,10 +81,27 @@ class LeetCodeManager extends EventEmitter { env: createEnvOption(), }); - childProc.stdout.on("data", (data: string | Buffer) => { + childProc.stdout.on("data", async (data: string | Buffer) => { data = data.toString(); - result = result.concat(data); leetCodeChannel.append(data); + if (data.includes("twoFactorCode")) { + const twoFactor: string | undefined = await vscode.window.showInputBox({ + prompt: "Enter two-factor code.", + validateInput: (s: string): string | undefined => s && s.trim() ? undefined : "The input must not be empty", + }); + if (!twoFactor) { + childProc.kill(); + return resolve(undefined); + } + childProc.stdin.write(`${twoFactor}\n`); + childProc.stdin.end(); + } else { + const match: RegExpMatchArray | null = data.match(/(?:.*)Successfully .*login as (.*)/i); + if (match && match[1]) { + childProc.stdin.end(); + return resolve(match[1]); + } + } }); childProc.stderr.on("data", (data: string | Buffer) => leetCodeChannel.append(data.toString())); @@ -80,13 +126,9 @@ class LeetCodeManager extends EventEmitter { return resolve(undefined); } childProc.stdin.write(`${pwd}\n`); - childProc.stdin.end(); - childProc.on("close", () => { - const match: RegExpMatchArray | null = result.match(/(?:.*) Successfully (login|cookie login) as (.*)/i); - if (match && match[2]) { - resolve(match[2]); - } else { - reject(new Error(`Failed to ${inMessage}.`)); + childProc.on("close", (code: number) => { + if (code !== 0) { + reject(new Error("Failed to login.")); } }); }); diff --git a/src/shared.ts b/src/shared.ts index 78518454..5f1039e4 100644 --- a/src/shared.ts +++ b/src/shared.ts @@ -12,6 +12,13 @@ export enum UserStatus { SignedOut = 2, } +export const loginArgsMapping: Map = new Map([ + ["LeetCode", "-l"], + ["Cookie", "-c"], + ["GitHub", "-g"], + ["LinkedIn", "-i"], +]); + export const languages: string[] = [ "bash", "c",