Skip to content

Commit c20a2d5

Browse files
yihong0618jdneo
authored andcommitted
add thrid party login -- GitHub and LinkedIn (LeetCode-OpenSource#496)
1 parent 9767d72 commit c20a2d5

File tree

6 files changed

+66
-28
lines changed

6 files changed

+66
-28
lines changed

README.md

+1-3
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,9 @@ Thanks for [@yihong0618](https://github.com/yihong0618) provided a workaround wh
5151

5252
- Simply click `Sign in to LeetCode` in the `LeetCode Explorer` will let you **sign in** with your LeetCode account.
5353

54-
- You can also use the following command to sign in/sign in (by cookie)/out:
54+
- You can also use the following command to sign in/out:
5555
- **LeetCode: Sign in**
56-
- **LeetCode: Sign in (by cookie)**
5756
- **LeetCode: Sign out**
58-
5957
---
6058

6159
### Switch Endpoint

docs/README_zh-CN.md

-2
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,7 @@
5353

5454
- 你也可以使用下来命令登入或利用cookie登入或登出:
5555
- **LeetCode: Sign in**
56-
- **LeetCode: Sign in (by cookie)**
5756
- **LeetCode: Sign out**
58-
5957
---
6058

6159
### 切换 LeetCode 版本

package.json

+1-7
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,11 @@
3838
"onCommand:leetcode.testSolution",
3939
"onCommand:leetcode.submitSolution",
4040
"onCommand:leetcode.switchDefaultLanguage",
41-
"onCommand:leetcode.signinByCookie",
4241
"onView:leetCodeExplorer"
4342
],
4443
"main": "./out/src/extension",
4544
"contributes": {
4645
"commands": [
47-
{
48-
"command": "leetcode.signinByCookie",
49-
"title": "Sign In by Cookie",
50-
"category": "LeetCode"
51-
},
5246
{
5347
"command": "leetcode.deleteCache",
5448
"title": "Delete Cache",
@@ -689,6 +683,6 @@
689683
"markdown-it": "^8.4.2",
690684
"require-from-string": "^2.0.2",
691685
"unescape-js": "^1.1.1",
692-
"vsc-leetcode-cli": "2.6.19"
686+
"vsc-leetcode-cli": "2.6.20"
693687
}
694688
}

src/extension.ts

-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
5151
vscode.commands.registerCommand("leetcode.deleteCache", () => cache.deleteCache()),
5252
vscode.commands.registerCommand("leetcode.toggleLeetCodeCn", () => plugin.switchEndpoint()),
5353
vscode.commands.registerCommand("leetcode.signin", () => leetCodeManager.signIn()),
54-
vscode.commands.registerCommand("leetcode.signinByCookie", () => leetCodeManager.signIn(true)),
5554
vscode.commands.registerCommand("leetcode.signout", () => leetCodeManager.signOut()),
5655
vscode.commands.registerCommand("leetcode.manageSessions", () => session.manageSessions()),
5756
vscode.commands.registerCommand("leetcode.previewProblem", (node: LeetCodeNode) => show.previewProblem(node)),

src/leetCodeManager.ts

+57-15
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { EventEmitter } from "events";
66
import * as vscode from "vscode";
77
import { leetCodeChannel } from "./leetCodeChannel";
88
import { leetCodeExecutor } from "./leetCodeExecutor";
9-
import { UserStatus } from "./shared";
9+
import { IQuickItemEx, loginArgsMapping, UserStatus } from "./shared";
1010
import { createEnvOption } from "./utils/cpUtils";
1111
import { DialogType, promptForOpenOutputChannel } from "./utils/uiUtils";
1212
import * 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(/(?:.*)Successfully .*login as (.*)/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(/(?:.*) Successfully (login|cookie login) as (.*)/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
});

src/shared.ts

+7
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ export enum UserStatus {
1212
SignedOut = 2,
1313
}
1414

15+
export const loginArgsMapping: Map<string, string> = new Map([
16+
["LeetCode", "-l"],
17+
["Cookie", "-c"],
18+
["GitHub", "-g"],
19+
["LinkedIn", "-i"],
20+
]);
21+
1522
export const languages: string[] = [
1623
"bash",
1724
"c",

0 commit comments

Comments
 (0)