Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
jdneo merged 5 commits intoleetcode-tools:masterfromyihong0618:master
Dec 24, 2019
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletionsREADME.md
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -38,11 +38,13 @@ Great thanks to leetcode.com, a really awesome website!

## Quick Start

Read help first $ leetcode help
Login with your leetcode account $ leetcode user -l
Cookie login with cookie $ leetcode user -c
Browse all questions $ leetcode list
Choose one question $ leetcode show 1 -g -l cpp
Read help first $ leetcode help
Login with your leetcode account $ leetcode user -l
Login with third party account--GitHub $ leetcode user -g
Login with third party account--LinkedIn $ leetcode user -i
Cookie login with cookie $ leetcode user -c
Browse all questions $ leetcode list
Choose one question $ leetcode show 1 -g -l cpp
Coding it!
Run test(s) and pray... $ leetcode test ./two-sum.cpp -t '[3,2,4]\n7'
Submit final solution! $ leetcode submit ./two-sum.cpp
Run test(s) and pray...$ leetcode test ./two-sum.cpp -t '[3,2,4]\n7'
Submit final solution!$ leetcode submit ./two-sum.cpp
98 changes: 69 additions & 29 deletionslib/commands/user.js
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,28 +15,42 @@ const cmd = {
desc: 'Manage account',
builder: function(yargs) {
return yargs
.option('l', {
alias: 'login',
type: 'boolean',
default: false,
describe: 'Login'
})
.option('c', {
alias: 'cookie',
type: 'boolean',
default: false,
describe: 'cookieLogin'
})
.option('L', {
alias: 'logout',
type: 'boolean',
default: false,
describe: 'Logout'
})
.example(chalk.yellow('leetcode user'), 'Show current user')
.example(chalk.yellow('leetcode user -l'), 'User login')
.example(chalk.yellow('leetcode user -c'), 'User Cookie login')
.example(chalk.yellow('leetcode user -L'), 'User logout');
.option('l', {
alias: 'login',
type: 'boolean',
default: false,
describe: 'Login'
})
.option('c', {
alias: 'cookie',
type: 'boolean',
default: false,
describe: 'cookieLogin'
})
.option('g', {
alias: 'github',
type: 'boolean',
default: false,
describe: 'githubLogin'
})
.option('i', {
alias: 'linkedin',
type: 'boolean',
default: false,
describe: 'linkedinLogin'
})
.option('L', {
alias: 'logout',
type: 'boolean',
default: false,
describe: 'Logout'
})
.example(chalk.yellow('leetcode user'), 'Show current user')
.example(chalk.yellow('leetcode user -l'), 'User login')
.example(chalk.yellow('leetcode user -c'), 'User Cookie login')
.example(chalk.yellow('leetcode user -g'), 'User GitHub login')
.example(chalk.yellow('leetcode user -i'), 'User LinkedIn login')
.example(chalk.yellow('leetcode user -L'), 'User logout');
}
};

Expand DownExpand Up@@ -66,6 +80,32 @@ cmd.handler = function(argv) {
log.info('Successfully logout as', chalk.yellow(user.name));
else
log.fail('You are not login yet?');
// third parties
} else if (argv.github || argv.linkedin) {
// add future third parties here
const functionMap = new Map(
[
['g', core.githubLogin],
['github', core.githubLogin],
['i', core.linkedinLogin],
['linkedin', core.linkedinLogin],
]
);
const keyword = Object.entries(argv).filter((i) => (i[1] === true))[0][0];
const coreFunction = functionMap.get(keyword);
prompt.colors = false;
prompt.message = '';
prompt.start();
prompt.get([
{name: 'login', required: true},
{name: 'pass', required: true, hidden: true}
], function(e, user) {
if (e) return log.fail(e);
coreFunction(user, function(e, user) {
if (e) return log.fail(e);
log.info('Successfully third party login as', chalk.yellow(user.name));
});
});
} else if (argv.cookie) {
// session
prompt.colors = false;
Expand All@@ -75,22 +115,22 @@ cmd.handler = function(argv) {
{name: 'login', required: true},
{name: 'cookie', required: true}
], function(e, user) {
if (e) return log.fail(e)
core.cookieLogin(user, function(e, user) {
if (e) return log.fail(e);
log.info('Successfully cookie login as', chalk.yellow(user.name));
core.cookieLogin(user, function(e, user) {
if (e) return log.fail(e);
log.info('Successfully cookie login as', chalk.yellow(user.name));
});
});
} else {
} else {
// show current user
user = session.getUser();
if (user) {
log.info(chalk.gray(sprintf(' %-9s %-20s %s', 'Premium', 'User', 'Host')));
log.info(chalk.gray('-'.repeat(60)));
log.printf(' %s %-20s %s',
h.prettyText('', user.paid || false),
chalk.yellow(user.name),
config.sys.urls.base);
h.prettyText('', user.paid || false),
chalk.yellow(user.name),
config.sys.urls.base);
} else
return log.fail('You are not login yet?');
}
Expand Down
10 changes: 7 additions & 3 deletionslib/config.js
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -34,6 +34,10 @@ const DEFAULT_CONFIG = {
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/',
Expand DownExpand Up@@ -79,15 +83,15 @@ function Config() {}

Config.prototype.init = function() {
nconf.file('local', file.configFile())
.add('global', {type: 'literal', store: DEFAULT_CONFIG})
.defaults({});
.add('global', {type: 'literal', store: DEFAULT_CONFIG})
.defaults({});

const cfg = nconf.get();
nconf.remove('local');
nconf.remove('global');

// HACK: remove old style configs
for (let x in cfg) {
for (const x in cfg) {
if (x === x.toUpperCase()) delete cfg[x];
}
delete DEFAULT_CONFIG.type;
Expand Down
131 changes: 115 additions & 16 deletionslib/plugins/leetcode.js
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -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');
Expand DownExpand Up@@ -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',
Expand DownExpand Up@@ -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);
});
Expand DownExpand Up@@ -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
Expand DownExpand Up@@ -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';
}

Expand DownExpand Up@@ -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;
Expand DownExpand Up@@ -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.linkedinLogin = function(user, cb) {
const leetcodeUrl = config.sys.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) {
if ( resp.statusCode !== 200) {
return cb('Get LinkedIn session failed');
}
const authenticityToken = body.match(/input name="loginCsrfParam" value="(.*)" /);
if (authenticityToken === null) {
return cb('Get LinkedIn token failed');
}
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');
}
const cookieData = parseCookie(resp.request.headers.cookie, cb);
saveAndGetUser(user, cb, cookieData);
});
});
});
};

module.exports = plugin;

[8]ページ先頭

©2009-2025 Movatter.jp