-
Notifications
You must be signed in to change notification settings - Fork 51
add third party github login for future updates in vscode-leetcode #34
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
Changes from 3 commits
04b4dc1
51ca691
57e39f8
3663a98
a3c2dc6
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 |
---|---|---|
|
@@ -51,7 +51,7 @@ plugin.checkError = function(e, resp, expectedStatus) { | |
|
||
plugin.init = function() { | ||
config.app = 'leetcode'; | ||
} | ||
}; | ||
|
||
plugin.getProblems = function(cb) { | ||
log.debug('running leetcode.getProblems'); | ||
|
@@ -95,7 +95,7 @@ plugin.getCategoryProblems = function(category, cb) { | |
} | ||
|
||
const problems = json.stat_status_pairs | ||
.filter(p => !p.stat.question__hide) | ||
.filter((p) => !p.stat.question__hide) | ||
.map(function(p) { | ||
return { | ||
state: p.status || 'None', | ||
|
@@ -167,7 +167,7 @@ plugin.getProblem = function(problem, cb) { | |
problem.testable = q.enableRunCode; | ||
problem.templateMeta = JSON.parse(q.metaData); | ||
// @si-yao: seems below property is never used. | ||
//problem.discuss = q.discussCategoryId; | ||
// problem.discuss = q.discussCategoryId; | ||
|
||
return cb(null, problem); | ||
}); | ||
|
@@ -254,9 +254,9 @@ function formatResult(result) { | |
}; | ||
|
||
x.error = _.chain(result) | ||
.pick((v, k) => /_error$/.test(k) && v.length > 0) | ||
.values() | ||
.value(); | ||
.pick((v, k) => /_error$/.test(k) && v.length > 0) | ||
.values() | ||
.value(); | ||
|
||
if (/[runcode|interpret].*/.test(result.submission_id)) { | ||
// It's testing | ||
|
@@ -374,8 +374,8 @@ plugin.starProblem = function(problem, starred, cb) { | |
}; | ||
} else { | ||
opts.url = config.sys.urls.favorite_delete | ||
.replace('$hash', user.hash) | ||
.replace('$id', problem.id); | ||
.replace('$hash', user.hash) | ||
.replace('$id', problem.id); | ||
opts.method = 'DELETE'; | ||
} | ||
|
||
|
@@ -508,7 +508,7 @@ plugin.signin = function(user, cb) { | |
plugin.getUser = function(user, cb) { | ||
plugin.getFavorites(function(e, favorites) { | ||
if (!e) { | ||
const f = favorites.favorites.private_favorites.find(f => f.name === 'Favorite'); | ||
const f = favorites.favorites.private_favorites.find((f) => f.name === 'Favorite'); | ||
if (f) { | ||
user.hash = f.id_hash; | ||
user.name = favorites.user_name; | ||
|
@@ -538,19 +538,118 @@ plugin.login = function(user, cb) { | |
}); | ||
}; | ||
|
||
plugin.cookieLogin = function(user, cb) { | ||
// re pattern for cookie chrome or firefox | ||
function parseCookie(cookie, cb) { | ||
const SessionPattern = /LEETCODE_SESSION=(.+?)(;|$)/; | ||
const csrfPattern = /csrftoken=(.+?)(;|$)/; | ||
const reSessionResult = SessionPattern.exec(user.cookie); | ||
const reCsrfResult = csrfPattern.exec(user.cookie); | ||
const reSessionResult = SessionPattern.exec(cookie); | ||
const reCsrfResult = csrfPattern.exec(cookie); | ||
if (reSessionResult === null || reCsrfResult === null) { | ||
return cb('invalid cookie?') | ||
return cb('invalid cookie?'); | ||
} | ||
user.sessionId = reSessionResult[1]; | ||
user.sessionCSRF = reCsrfResult[1]; | ||
return { | ||
sessionId: reSessionResult[1], | ||
sessionCSRF: reCsrfResult[1], | ||
}; | ||
} | ||
|
||
function saveAndGetUser(user, cb, cookieData) { | ||
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; | ||
user.sessionCSRF = cookieData.sessionCSRF; | ||
session.saveUser(user); | ||
plugin.getUser(user, cb); | ||
}; | ||
|
||
plugin.githubLogin = function(user, cb) { | ||
const leetcodeUrl = config.sys.urls.github_login; | ||
const _request = request.defaults({jar: true}); | ||
_request('https://github.com/login', 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', | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/x-www-form-urlencoded', | ||
}, | ||
followAllRedirects: true, | ||
form: { | ||
'login': user.login, | ||
'password': user.pass, | ||
'authenticity_token': authenticityToken[1], | ||
'utf8': encodeURIComponent('✓'), | ||
'commit': encodeURIComponent('Sign in') | ||
}, | ||
}; | ||
_request(options, function(e, resp, body) { | ||
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'); | ||
} | ||
const cookieData = parseCookie(resp.request.headers.cookie, cb); | ||
saveAndGetUser(user, cb, cookieData); | ||
}); | ||
}); | ||
}); | ||
}; | ||
|
||
plugin.linkinedLogin = function(user, cb) { | ||
const leetcodeUrl = config.sys.urls.linkined_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) { | ||
if ( resp.statusCode !== 200) { | ||
return cb('Get linkedin session failed'); | ||
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. linkedin -> LinkedIn |
||
} | ||
const authenticityToken = body.match(/input name="loginCsrfParam" value="(.*)" /); | ||
if (authenticityToken === null) { | ||
return cb('Get Linkedin token failed'); | ||
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. |
||
} | ||
const options = { | ||
url: 'https://www.linkedin.com/uas/login-submit', | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/x-www-form-urlencoded', | ||
}, | ||
followAllRedirects: true, | ||
form: { | ||
'session_key': user.login, | ||
'session_password': user.pass, | ||
'loginCsrfParam': authenticityToken[1], | ||
'trk': 'guest_homepage-basic_sign-in-submit' | ||
}, | ||
}; | ||
_request(options, function(e, resp, body) { | ||
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'); | ||
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. LeetCode 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 for that, I will correct them~ |
||
} | ||
const cookieData = parseCookie(resp.request.headers.cookie, cb); | ||
saveAndGetUser(user, cb, cookieData); | ||
}); | ||
}); | ||
}); | ||
}; | ||
|
||
module.exports = plugin; |
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.
leetcode -> LeetCode