Skip to content

Commit

Permalink
feat: re-add cookie-based login method (#969)
Browse files Browse the repository at this point in the history
* feat: re-add cookie-based login method

* chore: optimize tslint config

* chore : change build.yml

---------

Co-authored-by: leo.zhao <zale0201@gmail.com>
  • Loading branch information
tomoyachen and leozhao21 authored Jul 30, 2024
1 parent b495812 commit bbc041d
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 67 deletions.
21 changes: 0 additions & 21 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,24 +48,3 @@ jobs:

- name: VSCE Packge
run: npx vsce package

darwin:
name: macOS
runs-on: macos-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v2

- name: Setup Node.js environment
uses: actions/setup-node@v2
with:
node-version: 14

- name: Install Node.js modules
run: npm install

- name: Lint
run: npm run lint

- name: VSCE Packge
run: npx vsce package
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"editor.formatOnSave": true,
"editor.formatOnSave": false,
"editor.insertSpaces": true,
"editor.tabSize": 4,
"files.insertFinalNewline": true,
Expand Down
83 changes: 67 additions & 16 deletions src/leetCodeManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import { EventEmitter } from "events";
import * as vscode from "vscode";
import { leetCodeChannel } from "./leetCodeChannel";
import { leetCodeExecutor } from "./leetCodeExecutor";
import { Endpoint, loginArgsMapping, urls, urlsCn, UserStatus } from "./shared";
import { Endpoint, IQuickItemEx, loginArgsMapping, urls, urlsCn, UserStatus } from "./shared";
import { createEnvOption } from "./utils/cpUtils";
import { DialogType, openUrl, promptForOpenOutputChannel } from "./utils/uiUtils";
import * as wsl from "./utils/wslUtils";
import { getLeetCodeEndpoint } from "./commands/plugin";
import { globalState } from "./globalState";
import { queryUserData } from "./request/query-user-data";
import { parseQuery, sleep } from "./utils/toolUtils";
import { parseQuery } from "./utils/toolUtils";

class LeetCodeManager extends EventEmitter {
private currentUser: string | undefined;
Expand Down Expand Up @@ -42,6 +42,19 @@ class LeetCodeManager extends EventEmitter {
}
}

private async updateUserStatusWithCookie(cookie: string): Promise<void> {
globalState.setCookie(cookie);
const data = await queryUserData();
globalState.setUserStatus(data);
await this.setCookieToCli(cookie, data.username);
if (data.username) {
vscode.window.showInformationMessage(`Successfully ${data.username}.`);
this.currentUser = data.username;
this.userStatus = UserStatus.SignedIn;
this.emit("statusChanged");
}
}

public async handleUriSignIn(uri: vscode.Uri): Promise<void> {
try {
await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification }, async (progress: vscode.Progress<{}>) => {
Expand All @@ -52,24 +65,61 @@ class LeetCodeManager extends EventEmitter {
promptForOpenOutputChannel(`Failed to get cookie. Please log in again`, DialogType.error);
return;
}
globalState.setCookie(cookie);
const data = await queryUserData();
globalState.setUserStatus(data);
await this.setCookieToCli(cookie, data.username);
if (data.username) {
vscode.window.showInformationMessage(`Successfully ${data.username}.`);
this.currentUser = data.username;
this.userStatus = UserStatus.SignedIn;
this.emit("statusChanged");
}

await this.updateUserStatusWithCookie(cookie)

});
} catch (error) {
promptForOpenOutputChannel(`Failed to log in. Please open the output channel for details`, DialogType.error);
}
}

public async handleInputCookieSignIn(): Promise<void> {
const cookie: string | undefined = await vscode.window.showInputBox({
prompt: 'Enter LeetCode Cookie',
password: true,
ignoreFocusOut: true,
validateInput: (s: string): string | undefined =>
s ? undefined : 'Cookie must not be empty',
})

await this.updateUserStatusWithCookie(cookie || '')
}

public async signIn(): Promise<void> {
openUrl(this.getAuthLoginUrl());
const picks: Array<IQuickItemEx<string>> = []
picks.push(
{
label: 'Web Authorization',
detail: 'Open browser to authorize login on the website',
value: 'WebAuth',
description: '[Recommended]'
},
{
label: 'LeetCode Cookie',
detail: 'Use LeetCode cookie copied from browser to login',
value: 'Cookie',
}
)

const choice: IQuickItemEx<string> | undefined = await vscode.window.showQuickPick(picks)
if (!choice) {
return
}
const loginMethod: string = choice.value

if (loginMethod === 'WebAuth') {
openUrl(this.getAuthLoginUrl())
return
}

try {
await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: "Fetching user data..." }, async () => {
await this.handleInputCookieSignIn()
});
} catch (error) {
promptForOpenOutputChannel(`Failed to log in. Please open the output channel for details`, DialogType.error);
}
}

public async signOut(): Promise<void> {
Expand Down Expand Up @@ -136,15 +186,16 @@ class LeetCodeManager extends EventEmitter {
} else if (data.match(this.failRegex)) {
childProc.stdin?.end();
return reject(new Error("Faile to login"));
} else if (data.match(/login: /)) {
childProc.stdin?.write(`${name}\n`);
} else if (data.match(/cookie: /)) {
childProc.stdin?.write(`${cookie}\n`);
}
});

childProc.stderr?.on("data", (data: string | Buffer) => leetCodeChannel.append(data.toString()));

childProc.on("error", reject);
childProc.stdin?.write(`${name}\n`);
await sleep(800);
childProc.stdin?.write(`${cookie}\n`);
});
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/utils/httpUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export function LcAxios<T = any>(path: string, settings?: AxiosRequestConfig): A
}
return axios(path, {
headers: {
referer: referer,
referer,
"content-type": "application/json",
cookie,
...(settings && settings.headers),
Expand Down
2 changes: 1 addition & 1 deletion src/utils/toolUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export function parseQuery(query: string): { [key: string]: string } {
return queryObject;
}

let keyValuePairs = query.split("&");
const keyValuePairs = query.split("&");
keyValuePairs.forEach((pair) => {
const firstEqualsIndex = pair.indexOf("=");
if (firstEqualsIndex !== -1) {
Expand Down
2 changes: 1 addition & 1 deletion src/utils/trackingUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class TrackData implements ITrackData {
if (!Array.isArray(reportItems)) {
reportItems = [reportItems];
}
let randomId = getRandomString(60);
const randomId = getRandomString(60);
reportItems.forEach((item) => {
this.reportCache.push({
...item,
Expand Down
44 changes: 18 additions & 26 deletions tslint.json
Original file line number Diff line number Diff line change
@@ -1,36 +1,28 @@
{
"defaultSeverity": "error",
"extends": [
"tslint:recommended"
],
"extends": ["tslint:recommended"],
"jsRules": {},
"rules": {
"forin": false,
"object-literal-sort-keys": false,
"indent": [
true,
"spaces"
],
"ordered-imports": [false],
"indent": [true, "spaces"],
"no-string-literal": false,
"no-namespace": false,
"max-line-length": [
false,
120
],
"typedef": [
true,
"call-signature",
"arrow-call-signature",
"parameter",
"arrow-parameter",
"property-declaration",
"variable-declaration",
"member-variable-declaration"
],
"variable-name": [
true,
"allow-leading-underscore"
]
"max-line-length": [false, 120],
"typedef": false,
"no-implicit-dependencies": [true, ["vscode"]],
"trailing-comma": false,
"no-any": false,
"object-literal-key-quotes": [true, "consistent-as-needed"],
"prefer-object-spread": false,
"no-unnecessary-await": false,
"semicolon": [false],
"quotemark": [false],
"member-ordering": [false],
"variable-name": [false],
"curly": false,
"interface-over-type-literal": [false],
"no-unused-expression": false
},
"rulesDirectory": []
}

0 comments on commit bbc041d

Please sign in to comment.