-
Notifications
You must be signed in to change notification settings - Fork 51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
solve GitHub login two-factor auth problem and add new node package p… #35
Changes from 6 commits
5ef6c1b
f7a6b53
53b3446
294dbe2
94ac8a4
3122ac7
e3680fe
1cdf7f8
8c1159e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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); | ||
|
@@ -552,11 +552,36 @@ function parseCookie(cookie, cb) { | |
}; | ||
} | ||
|
||
function saveAndGetUser(user, cb, cookieData) { | ||
user.sessionId = cookieData.sessionId; | ||
user.sessionCSRF = cookieData.sessionCSRF; | ||
session.saveUser(user); | ||
plugin.getUser(user, 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`); | ||
jdneo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
let cookieData = {}; | ||
if (leetcodeUrl.includes('cn')) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
cookieData = parseCNCookie(resp.request.headers.cookie, body, cb); | ||
} else cookieData = parseCookie(resp.request.headers.cookie, cb); | ||
jdneo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
user.sessionId = cookieData.sessionId; | ||
user.sessionCSRF = cookieData.sessionCSRF; | ||
session.saveUser(user); | ||
plugin.getUser(user, cb); | ||
}); | ||
} | ||
|
||
plugin.cookieLogin = function(user, cb) { | ||
|
@@ -568,15 +593,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', | ||
|
@@ -594,27 +620,50 @@ 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 === urls.github_tf_redirect) { | ||
cb('Your GitHub are using two-factor authentication'); | ||
jdneo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// 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: 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, config.sys.login_methods.GitHub); | ||
}); | ||
} else { | ||
requestLeetcodeAndSave(_request, leetcodeUrl, user, cb, config.sys.login_methods.GitHub); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can the calling of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, these two are with different session(_request), the first one is two-factor, the second one is normal. Both need. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see. How about if (resp.request.uri.href !== urls.github_tf_redirect) {
return requestLeetcodeAndSave(_request, leetcodeUrl, user, cb, config.sys.login_methods.GitHub);
}
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 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, config.sys.login_methods.GitHub);
}); which can save some indentions. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes! Very clean code. Thank you. |
||
} | ||
}); | ||
}); | ||
}; | ||
|
||
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'); | ||
} | ||
|
@@ -623,7 +672,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', | ||
|
@@ -640,14 +689,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, config.sys.login_methods.LinkedIn); | ||
}); | ||
}); | ||
}; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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" | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This field can also be removed