From 5ef6c1b5c0302056ef3ddf12af62565cdd2d6d86 Mon Sep 17 00:00:00 2001 From: yihong0618 Date: Tue, 24 Dec 2019 19:54:58 +0800 Subject: [PATCH 1/7] solve GitHub login two-factor auth problem and add new node package prompt-sync --- lib/plugins/leetcode.js | 61 ++++++++++++++++++++++++++++++----------- package.json | 1 + 2 files changed, 46 insertions(+), 16 deletions(-) diff --git a/lib/plugins/leetcode.js b/lib/plugins/leetcode.js index 004a6034..93184a1a 100644 --- a/lib/plugins/leetcode.js +++ b/lib/plugins/leetcode.js @@ -333,7 +333,7 @@ plugin.getSubmissions = function(problem, cb) { // FIXME: this only return the 1st 20 submissions, we should get next if necessary. const submissions = JSON.parse(body).submissions_dump; - for (let submission of submissions) + for (const submission of submissions) submission.id = _.last(_.compact(submission.url.split('/'))); return cb(null, submissions); @@ -559,6 +559,20 @@ function saveAndGetUser(user, cb, cookieData) { plugin.getUser(user, cb); } +function requestLeetcodeAndSave(request, leetcodeUrl, user, cb) { + request.get({url: leetcodeUrl}, function(e, resp, body) { + const redirectUri = resp.request.uri.href; + if (redirectUri !== 'https://leetcode.com/') { + return cb('LinkedIn login failed or LinkedIn did not link to LeetCode'); + } + const cookieData = parseCookie(resp.request.headers.cookie, cb); + user.sessionId = cookieData.sessionId; + user.sessionCSRF = cookieData.sessionCSRF; + session.saveUser(user); + plugin.getUser(user, cb); + }); +} + plugin.cookieLogin = function(user, cb) { const cookieData = parseCookie(user.cookie, cb); user.sessionId = cookieData.sessionId; @@ -594,14 +608,36 @@ plugin.githubLogin = function(user, cb) { if (resp.statusCode !== 200) { return cb('GitHub login failed'); } - _request.get({url: leetcodeUrl}, function(e, resp, body) { - const redirectUri = resp.request.uri.href; - if (redirectUri !== 'https://leetcode.com/') { - return cb('GitHub login failed or GitHub did not link to LeetCode'); + if (resp.request.uri.href == 'https://github.com/sessions/two-factor') { + cb('Your Github are using two-factor authentication'); + // read two-factor code must be sync. + const twoFactorcode = require('prompt-sync')()('Please enter your two-factor code: '); + const authenticityTokenTwoFactor = body.match(/name="authenticity_token" value="(.*?)"/); + if (authenticityTokenTwoFactor === null) { + return cb('Get GitHub two-factor token failed'); } - const cookieData = parseCookie(resp.request.headers.cookie, cb); - saveAndGetUser(user, cb, cookieData); - }); + const optionsTwoFactor = { + url: 'https://github.com/sessions/two-factor', + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + followAllRedirects: true, + form: { + 'otp': twoFactorcode, + 'authenticity_token': authenticityTokenTwoFactor[1], + 'utf8': encodeURIComponent('✓'), + }, + }; + _request(optionsTwoFactor, function(e, resp, body) { + if (resp.request.uri.href === 'https://github.com/sessions/two-factor') { + return cb('Wrong two-factor code please check'); + } + requestLeetcodeAndSave(_request, leetcodeUrl, user, cb); + }); + } else { + requestLeetcodeAndSave(_request, leetcodeUrl, user, cb); + } }); }); }; @@ -640,14 +676,7 @@ plugin.linkedinLogin = function(user, cb) { if (resp.statusCode !== 200) { return cb('LinkedIn login failed'); } - _request.get({url: leetcodeUrl}, function(e, resp, body) { - const redirectUri = resp.request.uri.href; - if (redirectUri !== 'https://leetcode.com/') { - return cb('LinkedIn login failed or LinkedIn did not link to LeetCode'); - } - const cookieData = parseCookie(resp.request.headers.cookie, cb); - saveAndGetUser(user, cb, cookieData); - }); + requestLeetcodeAndSave(_request, leetcodeUrl, user, cb); }); }); }; diff --git a/package.json b/package.json index 0dea2348..33d6e7f9 100644 --- a/package.json +++ b/package.json @@ -72,6 +72,7 @@ "nock": "10.0.2", "nyc": "^13.3.0", "pkg": "^4.3.4", + "prompt-sync": "^4.2.0", "rewire": "4.0.1" } } From f7a6b53d6042c918f2f5b265125af68247dbdb06 Mon Sep 17 00:00:00 2001 From: yihong0618 Date: Tue, 24 Dec 2019 20:06:16 +0800 Subject: [PATCH 2/7] delete unused function and fix typo --- lib/plugins/leetcode.js | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/lib/plugins/leetcode.js b/lib/plugins/leetcode.js index 93184a1a..7268c56e 100644 --- a/lib/plugins/leetcode.js +++ b/lib/plugins/leetcode.js @@ -552,18 +552,11 @@ function parseCookie(cookie, cb) { }; } -function saveAndGetUser(user, cb, cookieData) { - user.sessionId = cookieData.sessionId; - user.sessionCSRF = cookieData.sessionCSRF; - session.saveUser(user); - plugin.getUser(user, cb); -} - -function requestLeetcodeAndSave(request, leetcodeUrl, user, cb) { +function requestLeetcodeAndSave(request, leetcodeUrl, user, cb, party) { request.get({url: leetcodeUrl}, function(e, resp, body) { const redirectUri = resp.request.uri.href; if (redirectUri !== 'https://leetcode.com/') { - return cb('LinkedIn login failed or LinkedIn did not link to LeetCode'); + return cb(`${party} login failed or ${party} did not link to LeetCode`); } const cookieData = parseCookie(resp.request.headers.cookie, cb); user.sessionId = cookieData.sessionId; @@ -633,10 +626,10 @@ plugin.githubLogin = function(user, cb) { if (resp.request.uri.href === 'https://github.com/sessions/two-factor') { return cb('Wrong two-factor code please check'); } - requestLeetcodeAndSave(_request, leetcodeUrl, user, cb); + requestLeetcodeAndSave(_request, leetcodeUrl, user, cb, 'GitHub'); }); } else { - requestLeetcodeAndSave(_request, leetcodeUrl, user, cb); + requestLeetcodeAndSave(_request, leetcodeUrl, user, cb, 'GitHub'); } }); }); @@ -676,7 +669,7 @@ plugin.linkedinLogin = function(user, cb) { if (resp.statusCode !== 200) { return cb('LinkedIn login failed'); } - requestLeetcodeAndSave(_request, leetcodeUrl, user, cb); + requestLeetcodeAndSave(_request, leetcodeUrl, user, cb, 'LinkedIn'); }); }); }; From 53b344667542af27a5fafd76d67bf7d9217d560f Mon Sep 17 00:00:00 2001 From: yihong0618 Date: Wed, 25 Dec 2019 22:09:09 +0800 Subject: [PATCH 3/7] format the code by review --- lib/config.js | 54 +++++++++++++++++++++++++++-------------- lib/plugins/leetcode.js | 34 ++++++++++++++------------ 2 files changed, 54 insertions(+), 34 deletions(-) diff --git a/lib/config.js b/lib/config.js index 049d20d4..8a798c44 100644 --- a/lib/config.js +++ b/lib/config.js @@ -31,24 +31,42 @@ const DEFAULT_CONFIG = { 'swift' ], urls: { - base: 'https://leetcode.com', - graphql: 'https://leetcode.com/graphql', - login: 'https://leetcode.com/accounts/login/', - // third part login base urls. TODO facebook google - github_login: 'https://leetcode.com/accounts/github/login/?next=%2F', - facebook_login: 'https://leetcode.com/accounts/facebook/login/?next=%2F', - linkedin_login: 'https://leetcode.com/accounts/linkedin_oauth2/login/?next=%2F', - problems: 'https://leetcode.com/api/problems/$category/', - problem: 'https://leetcode.com/problems/$slug/description/', - test: 'https://leetcode.com/problems/$slug/interpret_solution/', - session: 'https://leetcode.com/session/', - submit: 'https://leetcode.com/problems/$slug/submit/', - submissions: 'https://leetcode.com/api/submissions/$slug', - submission: 'https://leetcode.com/submissions/detail/$id/', - verify: 'https://leetcode.com/submissions/detail/$id/check/', - favorites: 'https://leetcode.com/list/api/questions', - favorite_delete: 'https://leetcode.com/list/api/questions/$hash/$id', - plugin: 'https://raw.githubusercontent.com/leetcode-tools/leetcode-cli-plugins/master/plugins/$name.js' + // base urls + base: 'https://leetcode.com', + graphql: 'https://leetcode.com/graphql', + login: 'https://leetcode.com/accounts/login/', + // third part login base urls. TODO facebook google + github_login: 'https://leetcode.com/accounts/github/login/?next=%2F', + facebook_login: 'https://leetcode.com/accounts/facebook/login/?next=%2F', + linkedin_login: 'https://leetcode.com/accounts/linkedin_oauth2/login/?next=%2F', + // redirect urls + leetcode_redirect: 'https://leetcode.com/', + github_tf_redirect: 'https://github.com/sessions/two-factor', + // simulate login urls + github_login_request: 'https://github.com/login', + github_session_request: 'https://github.com/session', + github_tf_session_request: 'https://github.com/sessions/two-factor', + linkedin_login_request: 'https://www.linkedin.com', + linkedin_session_request: 'https://www.linkedin.com/uas/login-submit', + // questions urls + problems: 'https://leetcode.com/api/problems/$category/', + problem: 'https://leetcode.com/problems/$slug/description/', + test: 'https://leetcode.com/problems/$slug/interpret_solution/', + session: 'https://leetcode.com/session/', + submit: 'https://leetcode.com/problems/$slug/submit/', + submissions: 'https://leetcode.com/api/submissions/$slug', + submission: 'https://leetcode.com/submissions/detail/$id/', + verify: 'https://leetcode.com/submissions/detail/$id/check/', + favorites: 'https://leetcode.com/list/api/questions', + favorite_delete: 'https://leetcode.com/list/api/questions/$hash/$id', + plugin: 'https://raw.githubusercontent.com/leetcode-tools/leetcode-cli-plugins/master/plugins/$name.js' + }, + // login methods enum + login_methods: { + LeetCode: 'LeetCode', + Cookie: 'Cookie', + GitHub: 'Github', + LinkedIn: 'LinkedIn' } }, diff --git a/lib/plugins/leetcode.js b/lib/plugins/leetcode.js index 7268c56e..2c4366ef 100644 --- a/lib/plugins/leetcode.js +++ b/lib/plugins/leetcode.js @@ -555,8 +555,8 @@ function parseCookie(cookie, cb) { function requestLeetcodeAndSave(request, leetcodeUrl, user, cb, party) { request.get({url: leetcodeUrl}, function(e, resp, body) { const redirectUri = resp.request.uri.href; - if (redirectUri !== 'https://leetcode.com/') { - return cb(`${party} login failed or ${party} did not link to LeetCode`); + if (redirectUri !== config.sys.urls.leetcode_redirect) { + return cb(`${party} login failed or ${party} did not connect to LeetCode`); } const cookieData = parseCookie(resp.request.headers.cookie, cb); user.sessionId = cookieData.sessionId; @@ -575,15 +575,16 @@ plugin.cookieLogin = function(user, cb) { }; plugin.githubLogin = function(user, cb) { - const leetcodeUrl = config.sys.urls.github_login; + const urls = config.sys.urls + const leetcodeUrl = urls.github_login; const _request = request.defaults({jar: true}); - _request('https://github.com/login', function(e, resp, body) { + _request(urls.github_login_request, function(e, resp, body) { const authenticityToken = body.match(/name="authenticity_token" value="(.*?)"/); if (authenticityToken === null) { return cb('Get GitHub token failed'); } const options = { - url: 'https://github.com/session', + url: urls.github_session_request, method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', @@ -601,8 +602,8 @@ plugin.githubLogin = function(user, cb) { if (resp.statusCode !== 200) { return cb('GitHub login failed'); } - if (resp.request.uri.href == 'https://github.com/sessions/two-factor') { - cb('Your Github are using two-factor authentication'); + if (resp.request.uri.href === urls.github_tf_redirect) { + cb('Your GitHub are using two-factor authentication'); // read two-factor code must be sync. const twoFactorcode = require('prompt-sync')()('Please enter your two-factor code: '); const authenticityTokenTwoFactor = body.match(/name="authenticity_token" value="(.*?)"/); @@ -610,7 +611,7 @@ plugin.githubLogin = function(user, cb) { return cb('Get GitHub two-factor token failed'); } const optionsTwoFactor = { - url: 'https://github.com/sessions/two-factor', + url: urls.github_tf_session_request, method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', @@ -623,27 +624,28 @@ plugin.githubLogin = function(user, cb) { }, }; _request(optionsTwoFactor, function(e, resp, body) { - if (resp.request.uri.href === 'https://github.com/sessions/two-factor') { - return cb('Wrong two-factor code please check'); + if (resp.request.uri.href === urls.github_tf_session_request) { + return cb('Invalid two-factor code please check'); } - requestLeetcodeAndSave(_request, leetcodeUrl, user, cb, 'GitHub'); + requestLeetcodeAndSave(_request, leetcodeUrl, user, cb, config.sys.login_methods.GitHub); }); } else { - requestLeetcodeAndSave(_request, leetcodeUrl, user, cb, 'GitHub'); + requestLeetcodeAndSave(_request, leetcodeUrl, user, cb, config.sys.login_methods.GitHub); } }); }); }; plugin.linkedinLogin = function(user, cb) { - const leetcodeUrl = config.sys.urls.linkedin_login; + const urls = config.sys.urls + const leetcodeUrl = urls.linkedin_login; const _request = request.defaults({ jar: true, headers: { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36' } }); - _request('https://www.linkedin.com', function(e, resp, body) { + _request(urls.linkedin_login_request, function(e, resp, body) { if ( resp.statusCode !== 200) { return cb('Get LinkedIn session failed'); } @@ -652,7 +654,7 @@ plugin.linkedinLogin = function(user, cb) { return cb('Get LinkedIn token failed'); } const options = { - url: 'https://www.linkedin.com/uas/login-submit', + url: urls.linkedin_session_request, method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', @@ -669,7 +671,7 @@ plugin.linkedinLogin = function(user, cb) { if (resp.statusCode !== 200) { return cb('LinkedIn login failed'); } - requestLeetcodeAndSave(_request, leetcodeUrl, user, cb, 'LinkedIn'); + requestLeetcodeAndSave(_request, leetcodeUrl, user, cb, config.sys.login_methods.LinkedIn); }); }); }; From 94ac8a45dfd0d44d7c63ed7d831162c36b559d53 Mon Sep 17 00:00:00 2001 From: yihong0618 Date: Fri, 27 Dec 2019 21:46:25 +0800 Subject: [PATCH 4/7] support GitHub and LinkedIn login for leetcode-cn.com --- lib/plugins/leetcode.cn.js | 32 ++++++++++++++++++-------------- lib/plugins/leetcode.js | 20 +++++++++++++++++++- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/lib/plugins/leetcode.cn.js b/lib/plugins/leetcode.cn.js index 4df528f3..07c78f98 100644 --- a/lib/plugins/leetcode.cn.js +++ b/lib/plugins/leetcode.cn.js @@ -17,20 +17,24 @@ var plugin = new Plugin(15, 'leetcode.cn', '2018.11.25', plugin.init = function() { config.app = 'leetcode.cn'; - config.sys.urls.base = 'https://leetcode-cn.com'; - config.sys.urls.login = 'https://leetcode-cn.com/accounts/login/'; - config.sys.urls.problems = 'https://leetcode-cn.com/api/problems/$category/'; - config.sys.urls.problem = 'https://leetcode-cn.com/problems/$slug/description/'; - config.sys.urls.graphql = 'https://leetcode-cn.com/graphql'; - config.sys.urls.problem_detail = 'https://leetcode-cn.com/graphql'; - config.sys.urls.test = 'https://leetcode-cn.com/problems/$slug/interpret_solution/'; - config.sys.urls.session = 'https://leetcode-cn.com/session/'; - config.sys.urls.submit = 'https://leetcode-cn.com/problems/$slug/submit/'; - config.sys.urls.submissions = 'https://leetcode-cn.com/api/submissions/$slug'; - config.sys.urls.submission = 'https://leetcode-cn.com/submissions/detail/$id/'; - config.sys.urls.verify = 'https://leetcode-cn.com/submissions/detail/$id/check/'; - config.sys.urls.favorites = 'https://leetcode-cn.com/list/api/questions'; - config.sys.urls.favorite_delete = 'https://leetcode-cn.com/list/api/questions/$hash/$id'; + config.sys.urls.base = 'https://leetcode-cn.com'; + config.sys.urls.login = 'https://leetcode-cn.com/accounts/login/'; + config.sys.urls.problems = 'https://leetcode-cn.com/api/problems/$category/'; + config.sys.urls.problem = 'https://leetcode-cn.com/problems/$slug/description/'; + config.sys.urls.graphql = 'https://leetcode-cn.com/graphql'; + config.sys.urls.problem_detail = 'https://leetcode-cn.com/graphql'; + config.sys.urls.test = 'https://leetcode-cn.com/problems/$slug/interpret_solution/'; + config.sys.urls.session = 'https://leetcode-cn.com/session/'; + config.sys.urls.submit = 'https://leetcode-cn.com/problems/$slug/submit/'; + config.sys.urls.submissions = 'https://leetcode-cn.com/api/submissions/$slug'; + config.sys.urls.submission = 'https://leetcode-cn.com/submissions/detail/$id/'; + config.sys.urls.verify = 'https://leetcode-cn.com/submissions/detail/$id/check/'; + config.sys.urls.favorites = 'https://leetcode-cn.com/list/api/questions'; + config.sys.urls.favorite_delete = 'https://leetcode-cn.com/list/api/questions/$hash/$id'; + // third parties + config.sys.urls.github_login = 'https://leetcode-cn.com/accounts/github/login/?next=%2F'; + config.sys.urls.linkedin_login = 'https://leetcode-cn.com/accounts/linkedin_oauth2/login/?next=%2F'; + config.sys.urls.leetcode_redirect = 'https://leetcode-cn.com/'; }; // FIXME: refactor those diff --git a/lib/plugins/leetcode.js b/lib/plugins/leetcode.js index 2c4366ef..1f8c3f5c 100644 --- a/lib/plugins/leetcode.js +++ b/lib/plugins/leetcode.js @@ -552,13 +552,31 @@ function parseCookie(cookie, cb) { }; } +// leetcode-cn.com Cookie is not the same as leetcode.com in third parties +function parseCNCookie(cookie, body, cb) { + const SessionPattern = /LEETCODE_SESSION=(.+?)(;|$)/; + const csrfPattern = /name="csrfmiddlewaretoken" value="(.*?)"/; + const reSessionResult = SessionPattern.exec(cookie); + const reCsrfResult = csrfPattern.exec(body); + if (reSessionResult === null || reCsrfResult === null) { + return cb('invalid cookie?'); + } + return { + sessionId: reSessionResult[1], + sessionCSRF: reCsrfResult[1], + }; +} + function requestLeetcodeAndSave(request, leetcodeUrl, user, cb, party) { request.get({url: leetcodeUrl}, function(e, resp, body) { const redirectUri = resp.request.uri.href; if (redirectUri !== config.sys.urls.leetcode_redirect) { return cb(`${party} login failed or ${party} did not connect to LeetCode`); } - const cookieData = parseCookie(resp.request.headers.cookie, cb); + let cookieData = {} + if (leetcodeUrl.includes('cn')) { + cookieData = parseCNCookie(resp.request.headers.cookie, body, cb); + } else cookieData = parseCookie(resp.request.headers.cookie, cb) user.sessionId = cookieData.sessionId; user.sessionCSRF = cookieData.sessionCSRF; session.saveUser(user); From 3122ac72f5e46aa31492bf22ebf3ce93dfa62d54 Mon Sep 17 00:00:00 2001 From: yihong0618 Date: Fri, 27 Dec 2019 21:49:54 +0800 Subject: [PATCH 5/7] lint --- lib/plugins/leetcode.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/plugins/leetcode.js b/lib/plugins/leetcode.js index 1f8c3f5c..44791588 100644 --- a/lib/plugins/leetcode.js +++ b/lib/plugins/leetcode.js @@ -573,10 +573,10 @@ function requestLeetcodeAndSave(request, leetcodeUrl, user, cb, party) { if (redirectUri !== config.sys.urls.leetcode_redirect) { return cb(`${party} login failed or ${party} did not connect to LeetCode`); } - let cookieData = {} + let cookieData = {}; if (leetcodeUrl.includes('cn')) { cookieData = parseCNCookie(resp.request.headers.cookie, body, cb); - } else cookieData = parseCookie(resp.request.headers.cookie, cb) + } else cookieData = parseCookie(resp.request.headers.cookie, cb); user.sessionId = cookieData.sessionId; user.sessionCSRF = cookieData.sessionCSRF; session.saveUser(user); @@ -593,7 +593,7 @@ plugin.cookieLogin = function(user, cb) { }; plugin.githubLogin = function(user, cb) { - const urls = config.sys.urls + const urls = config.sys.urls; const leetcodeUrl = urls.github_login; const _request = request.defaults({jar: true}); _request(urls.github_login_request, function(e, resp, body) { @@ -655,7 +655,7 @@ plugin.githubLogin = function(user, cb) { }; plugin.linkedinLogin = function(user, cb) { - const urls = config.sys.urls + const urls = config.sys.urls; const leetcodeUrl = urls.linkedin_login; const _request = request.defaults({ jar: true, From e3680fec38128f208483e1d3ededa240007ce88c Mon Sep 17 00:00:00 2001 From: yihong0618 Date: Mon, 30 Dec 2019 16:02:06 +0800 Subject: [PATCH 6/7] format naming by review and refactor the parse cookie function(include if cn test) to make it more clear, also fixed a tiny bug before --- lib/plugins/leetcode.js | 46 +++++++++++++++-------------------------- 1 file changed, 17 insertions(+), 29 deletions(-) diff --git a/lib/plugins/leetcode.js b/lib/plugins/leetcode.js index 44791588..1cde2b36 100644 --- a/lib/plugins/leetcode.js +++ b/lib/plugins/leetcode.js @@ -471,8 +471,8 @@ plugin.deleteSession = function(session, cb) { }; plugin.signin = function(user, cb) { - log.debug('running leetcode.signin'); - const spin = h.spin('Signing in leetcode.com'); + const isCN = config.app === 'leetcode.cn'; + const spin = isCN ? h.spin('Signing in leetcode-cn.com') : h.spin('Signing in leetcode.com'); request(config.sys.urls.login, function(e, resp, body) { spin.stop(); e = plugin.checkError(e, resp, 200); @@ -538,26 +538,18 @@ plugin.login = function(user, cb) { }); }; -function parseCookie(cookie, cb) { +function parseCookie(cookie, body, cb) { + const isCN = config.app === 'leetcode.cn'; const SessionPattern = /LEETCODE_SESSION=(.+?)(;|$)/; - const csrfPattern = /csrftoken=(.+?)(;|$)/; - const reSessionResult = SessionPattern.exec(cookie); - const reCsrfResult = csrfPattern.exec(cookie); - if (reSessionResult === null || reCsrfResult === null) { - return cb('invalid cookie?'); + let csrfPattern; + // leetcode-cn.com Cookie is not the same as leetcode.com in third parties + if (isCN) { + csrfPattern = /name="csrfmiddlewaretoken" value="(.*?)"/; + } else { + csrfPattern = /csrftoken=(.+?)(;|$)/; } - return { - sessionId: reSessionResult[1], - sessionCSRF: reCsrfResult[1], - }; -} - -// leetcode-cn.com Cookie is not the same as leetcode.com in third parties -function parseCNCookie(cookie, body, cb) { - const SessionPattern = /LEETCODE_SESSION=(.+?)(;|$)/; - const csrfPattern = /name="csrfmiddlewaretoken" value="(.*?)"/; const reSessionResult = SessionPattern.exec(cookie); - const reCsrfResult = csrfPattern.exec(body); + const reCsrfResult = csrfPattern.exec(isCN? body: cookie); if (reSessionResult === null || reCsrfResult === null) { return cb('invalid cookie?'); } @@ -567,16 +559,13 @@ function parseCNCookie(cookie, body, cb) { }; } -function requestLeetcodeAndSave(request, leetcodeUrl, user, cb, party) { +function requestLeetcodeAndSave(request, leetcodeUrl, user, cb) { request.get({url: leetcodeUrl}, function(e, resp, body) { const redirectUri = resp.request.uri.href; if (redirectUri !== config.sys.urls.leetcode_redirect) { - return cb(`${party} login failed or ${party} did not connect to LeetCode`); + return cb('Login failed. Please make sure the credential is correct.'); } - let cookieData = {}; - if (leetcodeUrl.includes('cn')) { - cookieData = parseCNCookie(resp.request.headers.cookie, body, cb); - } else cookieData = parseCookie(resp.request.headers.cookie, cb); + const cookieData = parseCookie(resp.request.headers.cookie, body, cb); user.sessionId = cookieData.sessionId; user.sessionCSRF = cookieData.sessionCSRF; session.saveUser(user); @@ -621,7 +610,6 @@ plugin.githubLogin = function(user, cb) { return cb('GitHub login failed'); } if (resp.request.uri.href === urls.github_tf_redirect) { - cb('Your GitHub are using two-factor authentication'); // read two-factor code must be sync. const twoFactorcode = require('prompt-sync')()('Please enter your two-factor code: '); const authenticityTokenTwoFactor = body.match(/name="authenticity_token" value="(.*?)"/); @@ -645,10 +633,10 @@ plugin.githubLogin = function(user, cb) { if (resp.request.uri.href === urls.github_tf_session_request) { return cb('Invalid two-factor code please check'); } - requestLeetcodeAndSave(_request, leetcodeUrl, user, cb, config.sys.login_methods.GitHub); + requestLeetcodeAndSave(_request, leetcodeUrl, user, cb); }); } else { - requestLeetcodeAndSave(_request, leetcodeUrl, user, cb, config.sys.login_methods.GitHub); + requestLeetcodeAndSave(_request, leetcodeUrl, user, cb); } }); }); @@ -689,7 +677,7 @@ plugin.linkedinLogin = function(user, cb) { if (resp.statusCode !== 200) { return cb('LinkedIn login failed'); } - requestLeetcodeAndSave(_request, leetcodeUrl, user, cb, config.sys.login_methods.LinkedIn); + requestLeetcodeAndSave(_request, leetcodeUrl, user, cb); }); }); }; From 1cdf7f85c22a086ab46a91b0543b98378679218d Mon Sep 17 00:00:00 2001 From: yihong0618 Date: Mon, 30 Dec 2019 16:39:14 +0800 Subject: [PATCH 7/7] delete unused config and make the github login function more clear by review --- lib/config.js | 7 ------ lib/plugins/leetcode.js | 53 ++++++++++++++++++++--------------------- 2 files changed, 26 insertions(+), 34 deletions(-) diff --git a/lib/config.js b/lib/config.js index 8a798c44..9fc26945 100644 --- a/lib/config.js +++ b/lib/config.js @@ -61,13 +61,6 @@ const DEFAULT_CONFIG = { favorite_delete: 'https://leetcode.com/list/api/questions/$hash/$id', plugin: 'https://raw.githubusercontent.com/leetcode-tools/leetcode-cli-plugins/master/plugins/$name.js' }, - // login methods enum - login_methods: { - LeetCode: 'LeetCode', - Cookie: 'Cookie', - GitHub: 'Github', - LinkedIn: 'LinkedIn' - } }, // but you will want change these diff --git a/lib/plugins/leetcode.js b/lib/plugins/leetcode.js index 1cde2b36..12d7ccbe 100644 --- a/lib/plugins/leetcode.js +++ b/lib/plugins/leetcode.js @@ -609,35 +609,34 @@ plugin.githubLogin = function(user, cb) { if (resp.statusCode !== 200) { return cb('GitHub login failed'); } - if (resp.request.uri.href === urls.github_tf_redirect) { - // read two-factor code must be sync. - const twoFactorcode = require('prompt-sync')()('Please enter your two-factor code: '); - const authenticityTokenTwoFactor = body.match(/name="authenticity_token" value="(.*?)"/); - if (authenticityTokenTwoFactor === null) { - return cb('Get GitHub two-factor token failed'); + if (resp.request.uri.href !== urls.github_tf_redirect) { + return requestLeetcodeAndSave(_request, leetcodeUrl, user, cb); + } + // read two-factor code must be sync. + const twoFactorcode = require('prompt-sync')()('Please enter your two-factor code: '); + const authenticityTokenTwoFactor = body.match(/name="authenticity_token" value="(.*?)"/); + if (authenticityTokenTwoFactor === null) { + return cb('Get GitHub two-factor token failed'); + } + const optionsTwoFactor = { + url: urls.github_tf_session_request, + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + followAllRedirects: true, + form: { + 'otp': twoFactorcode, + 'authenticity_token': authenticityTokenTwoFactor[1], + 'utf8': encodeURIComponent('✓'), + }, + }; + _request(optionsTwoFactor, function(e, resp, body) { + if (resp.request.uri.href === urls.github_tf_session_request) { + return cb('Invalid two-factor code please check'); } - const optionsTwoFactor = { - url: urls.github_tf_session_request, - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - followAllRedirects: true, - form: { - 'otp': twoFactorcode, - 'authenticity_token': authenticityTokenTwoFactor[1], - 'utf8': encodeURIComponent('✓'), - }, - }; - _request(optionsTwoFactor, function(e, resp, body) { - if (resp.request.uri.href === urls.github_tf_session_request) { - return cb('Invalid two-factor code please check'); - } - requestLeetcodeAndSave(_request, leetcodeUrl, user, cb); - }); - } else { requestLeetcodeAndSave(_request, leetcodeUrl, user, cb); - } + }); }); }); };