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

Lines changed: 1 addition & 3 deletions
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

Lines changed: 0 additions & 2 deletions
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

Lines changed: 1 addition & 7 deletions
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

Lines changed: 0 additions & 1 deletion
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

Lines changed: 57 additions & 15 deletions
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

Lines changed: 7 additions & 0 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy