mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-17 09:36:08 +08:00
Google OAuth
This commit is contained in:
1 parent
8476eac3b4
commit
d2173eeb38
12 files changed
+261
-117
No files matched your search
@@ -5,7 +5,7 @@ const fs = require('fs');
|
||||
const yaml = require('js-yaml');
|
||||
|
||||
const builtinLib = [
|
||||
'axios', 'download', 'i18n', 'mail', 'markdown',
|
||||
'jwt', 'download', 'i18n', 'mail', 'markdown',
|
||||
'md5', 'misc', 'paginate', 'hash.hydro', 'rank',
|
||||
'template', 'validator', 'nav', 'sysinfo', 'testdata.convert.ini',
|
||||
'readConfig', 'logger', 'useragent',
|
||||
|
||||
+109
-49
@@ -1,4 +1,4 @@
|
||||
const axios = require('axios');
|
||||
const superagent = require('superagent');
|
||||
const { Route, Handler } = require('../service/server.js');
|
||||
const user = require('../model/user');
|
||||
const token = require('../model/token');
|
||||
@@ -162,67 +162,127 @@ class UserSearchHandler extends Handler {
|
||||
}
|
||||
|
||||
class OauthHandler extends Handler {
|
||||
async github() {
|
||||
const [appid, [state]] = await Promise.all([
|
||||
system.get('oauth.githubappid'),
|
||||
token.add(token.TYPE_OAUTH, 600, { redirect: this.request.referer }),
|
||||
]);
|
||||
this.response.redirect = `https://github.com/login/oauth/authorize?client_id=${appid}&state=${state}`;
|
||||
}
|
||||
|
||||
async google() {
|
||||
const [appid, url, [state]] = await Promise.all([
|
||||
system.get('oauth.googleappid'),
|
||||
system.get('server.url'),
|
||||
token.add(token.TYPE_OAUTH, 600, { redirect: this.request.referer }),
|
||||
]);
|
||||
this.response.redirect = `https://accounts.google.com/o/oauth2/v2/auth?client_id=${appid}&response_type=code&redirect_uri=${url}oauth/google/callback&scope=https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile&state=${state}`;
|
||||
}
|
||||
|
||||
async get({ type }) {
|
||||
if (type === 'github') {
|
||||
const [appid, [state]] = await Promise.all([
|
||||
system.get('oauth.githubappid'),
|
||||
token.add(token.TYPE_OAUTH, 600, { redirect: this.request.referer }),
|
||||
]);
|
||||
this.response.redirect = `https://github.com/login/oauth/authorize?client_id=${appid}&state=${state}`;
|
||||
}
|
||||
if (type === 'github') await this.github();
|
||||
else if (type === 'google') await this.google();
|
||||
}
|
||||
}
|
||||
|
||||
class OauthCallbackHandler extends Handler {
|
||||
async get({ type, state, code }) {
|
||||
if (type === 'github') {
|
||||
const [appid, secret, url, s] = await Promise.all([
|
||||
system.get('oauth.githubappid'),
|
||||
system.get('oauth.githubsecret'),
|
||||
system.get('server.url'),
|
||||
token.get(state, token.TYPE_OAUTH),
|
||||
]);
|
||||
const res = await axios.post('https://github.com/login/oauth/access_token', {
|
||||
async github({ state, code }) {
|
||||
const [appid, secret, url, s] = await Promise.all([
|
||||
system.get('oauth.githubappid'),
|
||||
system.get('oauth.githubsecret'),
|
||||
system.get('server.url'),
|
||||
token.get(state, token.TYPE_OAUTH),
|
||||
]);
|
||||
const res = await superagent.post('https://github.com/login/oauth/access_token')
|
||||
.send({
|
||||
client_id: appid,
|
||||
client_secret: secret,
|
||||
code,
|
||||
redirect_uri: `${url}oauth/github/callback`,
|
||||
state,
|
||||
}, { headers: { accept: 'application/json' } });
|
||||
if (res.data.error) {
|
||||
throw new UserFacingError(
|
||||
res.data.error, res.data.error_description, res.data.error_uri,
|
||||
);
|
||||
}
|
||||
const t = res.data.access_token;
|
||||
const userInfo = await axios.get('https://api.github.com/user', {
|
||||
headers: {
|
||||
Authorization: `token ${t}`,
|
||||
},
|
||||
})
|
||||
.set('accept', 'application/json');
|
||||
if (res.body.error) {
|
||||
throw new UserFacingError(
|
||||
res.body.error, res.body.error_description, res.body.error_uri,
|
||||
);
|
||||
}
|
||||
const t = res.body.access_token;
|
||||
const userInfo = await superagent.get('https://api.github.com/user')
|
||||
.set('Authorization', `token ${t}`);
|
||||
const ret = {
|
||||
email: userInfo.body.mail,
|
||||
bio: userInfo.body.bio,
|
||||
uname: [userInfo.body.name, userInfo.body.login],
|
||||
};
|
||||
this.response.redirect = s.redirect;
|
||||
await token.del(s, token.TYPE_OAUTH);
|
||||
return ret;
|
||||
}
|
||||
|
||||
async google({
|
||||
code, scope, authuser, prompt, error, state,
|
||||
}) {
|
||||
if (error) throw new UserFacingError(error);
|
||||
console.log(scope, authuser, prompt);
|
||||
const [
|
||||
[appid, secret, url, proxy],
|
||||
s,
|
||||
] = await Promise.all([
|
||||
system.getMany([
|
||||
'oauth.googleappid', 'oauth.googlesecret', 'server.url', 'proxy',
|
||||
]),
|
||||
token.get(state, token.TYPE_OAUTH),
|
||||
]);
|
||||
const res = await superagent.post('https://oauth2.googleapis.com/token')
|
||||
.proxy(proxy)
|
||||
.send({
|
||||
client_id: appid,
|
||||
client_secret: secret,
|
||||
code,
|
||||
grant_type: 'authorization_code',
|
||||
redirect_uri: `${url}oauth/google/callback`,
|
||||
});
|
||||
const {
|
||||
email: mail, bio, name, login,
|
||||
} = userInfo.data;
|
||||
const udoc = await user.getByEmail('system', mail, true);
|
||||
if (udoc) {
|
||||
this.session.uid = udoc._id;
|
||||
await token.del(s, token.TYPE_OAUTH);
|
||||
} else {
|
||||
let uname;
|
||||
const nudoc = await user.getByUname('system', name, true);
|
||||
if (!nudoc) uname = name;
|
||||
else {
|
||||
const ludoc = await user.getByUname('system', login, true);
|
||||
if (!ludoc) uname = login;
|
||||
else uname = String.random(16);
|
||||
const payload = global.Hydro.lib.jwt.decode(res.body.id_token);
|
||||
await token.del(state, token.TYPE_OAUTH);
|
||||
this.response.redirect = s.redirect;
|
||||
return {
|
||||
email: payload.email,
|
||||
uname: [payload.given_name, payload.name, payload.family_name],
|
||||
viewLang: payload.locale.replace('-', '_'),
|
||||
};
|
||||
}
|
||||
|
||||
async get(args) {
|
||||
let r;
|
||||
if (args.type === 'github') r = await this.github(args);
|
||||
else if (args.type === 'google') r = await this.google(args);
|
||||
else throw new UserFacingError('Oauth type');
|
||||
const udoc = await user.getByEmail('system', r.email, true);
|
||||
if (udoc) {
|
||||
this.session.uid = udoc._id;
|
||||
} else {
|
||||
let username = '';
|
||||
r.uname = r.uname || [];
|
||||
r.uname.push(String.random(16));
|
||||
for (const uname of r.uname) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
const nudoc = await user.getByUname('system', uname, true);
|
||||
if (!nudoc) {
|
||||
username = uname;
|
||||
break;
|
||||
}
|
||||
const uid = await user.create({
|
||||
mail, uname, password: String.random(32), regip: this.request.ip,
|
||||
});
|
||||
await user.setById(uid, { bio, oauth: 'github' });
|
||||
this.session.uid = uid;
|
||||
}
|
||||
this.response.redirect = s.redirect;
|
||||
const uid = await user.create({
|
||||
mail: r.email, uname: username, password: String.random(32), regip: this.request.ip,
|
||||
});
|
||||
const $set = {
|
||||
oauth: args.type,
|
||||
};
|
||||
if (r.bio) $set.bio = r.bio;
|
||||
if (r.viewLang) $set.viewLang = r.viewLang;
|
||||
await user.setById(uid, $set);
|
||||
this.session.uid = uid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
const axios = require('axios');
|
||||
|
||||
async function get(url, options) {
|
||||
let res;
|
||||
try {
|
||||
res = await axios.get(url, options);
|
||||
} catch (e) {
|
||||
res = e;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
async function post(url, data, options) {
|
||||
let res;
|
||||
try {
|
||||
res = await axios.post(url, data, options);
|
||||
} catch (e) {
|
||||
res = e;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
global.Hydro.lib.axios = module.exports = { get, post };
|
||||
+10
-16
@@ -1,23 +1,17 @@
|
||||
const axios = require('axios');
|
||||
const superagent = require('superagent');
|
||||
const fs = require('fs');
|
||||
|
||||
async function download(url, path, retry = 3) {
|
||||
let r;
|
||||
try {
|
||||
const res = await axios.get(url, { responseType: 'stream' });
|
||||
if (path) {
|
||||
const w = await fs.createWriteStream(path);
|
||||
res.data.pipe(w);
|
||||
await new Promise((resolve, reject) => {
|
||||
w.on('finish', resolve);
|
||||
w.on('error', reject);
|
||||
});
|
||||
} else r = res.data;
|
||||
} catch (e) {
|
||||
if (retry) r = await download(url, path, retry - 1);
|
||||
else throw e;
|
||||
if (path) {
|
||||
const w = await fs.createWriteStream(path);
|
||||
await superagent.get(url).retry(retry).pipe(w);
|
||||
await new Promise((resolve, reject) => {
|
||||
w.on('finish', resolve);
|
||||
w.on('error', reject);
|
||||
});
|
||||
return path;
|
||||
}
|
||||
return r;
|
||||
return superagent.get(url);
|
||||
}
|
||||
|
||||
global.Hydro.lib.download = module.exports = download;
|
||||
@@ -0,0 +1,35 @@
|
||||
function decodeBase64WithUriEncoding(encodedText) {
|
||||
return Buffer.from(encodedText, 'base64').toString('utf8');
|
||||
}
|
||||
|
||||
function unescapedString(escapedString) {
|
||||
escapedString += new Array(5 - escapedString.length % 4).join('=');
|
||||
return escapedString.replace(/\-/g, '+').replace(/_/g, '/');
|
||||
}
|
||||
|
||||
function decodeJWT(idToken) {
|
||||
const token = idToken.split('.');
|
||||
if (token.length !== 3) {
|
||||
throw new Error('Invalid idToken');
|
||||
}
|
||||
try {
|
||||
const headerSegment = JSON.parse(decodeBase64WithUriEncoding(token[0]));
|
||||
const payloadSegment = JSON.parse(decodeBase64WithUriEncoding(token[1]));
|
||||
const signature = unescapedString(token[2]);
|
||||
return {
|
||||
dataToSign: [token[0], token[1]].join('.'),
|
||||
header: headerSegment,
|
||||
payload: payloadSegment,
|
||||
signature,
|
||||
};
|
||||
} catch (e) {
|
||||
throw new Error('Invalid payload');
|
||||
}
|
||||
}
|
||||
|
||||
function decode(idToken) {
|
||||
const decodedJWT = decodeJWT(idToken);
|
||||
return decodedJWT.payload;
|
||||
}
|
||||
|
||||
global.Hydro.lib.jwt = module.exports = { decode };
|
||||
+1
-1
@@ -75,8 +75,8 @@ async function messageHandler(worker, msg) {
|
||||
async function load() {
|
||||
global.nodeModules = {
|
||||
'adm-zip': require('adm-zip'),
|
||||
axios: require('axios'),
|
||||
bson: require('bson'),
|
||||
superagent: require('superagent'),
|
||||
'js-yaml': require('js-yaml'),
|
||||
mongodb: require('mongodb'),
|
||||
};
|
||||
|
||||
@@ -104,6 +104,9 @@ SystemSetting(
|
||||
Setting('setting_server', 'server.port', null, 8888, 'number', 'Server Port'),
|
||||
Setting('setting_oauth', 'oauth.githubappid', null, null, 'text', 'Github Oauth AppID'),
|
||||
Setting('setting_oauth', 'oauth.githubsecret', null, null, 'text', 'Github Oauth Secret'),
|
||||
Setting('setting_oauth', 'oauth.googleappid', null, null, 'text', 'Google Oauth ClientID'),
|
||||
Setting('setting_oauth', 'oauth.googlesecret', null, null, 'text', 'Google Oauth Secret'),
|
||||
Setting('setting_proxy', 'proxy', null, null, 'text', 'Proxy Server URL'),
|
||||
Setting('setting_constant', 'PROBLEM_PER_PAGE', null, 100, 'number', 'Problems per Page'),
|
||||
Setting('setting_constant', 'CONTEST_PER_PAGE', null, 20, 'number', 'Contests per Page'),
|
||||
Setting('setting_constant', 'DISCUSSION_PER_PAGE', null, 50, 'number', 'Discussion per Page'),
|
||||
|
||||
@@ -7,10 +7,25 @@ async function get(_id) {
|
||||
if (doc) return doc.value;
|
||||
return null;
|
||||
}
|
||||
|
||||
async function getMany(keys) {
|
||||
const docs = await coll.find({ _id: { $in: keys } }).toArray();
|
||||
const dict = {};
|
||||
const res = [];
|
||||
for (const doc of docs) {
|
||||
dict[doc._id] = doc.value;
|
||||
}
|
||||
for (const key of keys) {
|
||||
res.push(dict[key] || null);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
async function update(_id, operation, config) {
|
||||
await coll.findOneAndUpdate({ _id }, operation, config);
|
||||
return get(_id);
|
||||
}
|
||||
|
||||
async function set(_id, value) {
|
||||
await coll.findOneAndUpdate({ _id }, { $set: { value } }, { upsert: true });
|
||||
return get(_id);
|
||||
@@ -25,6 +40,7 @@ function inc(field) {
|
||||
|
||||
global.Hydro.model.system = module.exports = {
|
||||
get,
|
||||
getMany,
|
||||
update,
|
||||
inc,
|
||||
set,
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
const superagent = require('superagent');
|
||||
const proxy = require('superagent-proxy');
|
||||
|
||||
proxy(superagent);
|
||||
|
||||
const dict = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
|
||||
|
||||
String.random = function random(digit = 32) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
const assert = require('assert');
|
||||
|
||||
const { download, axios } = global.Hydro.lib;
|
||||
const { download } = global.Hydro.lib;
|
||||
const { superagent } = global.nodeModules;
|
||||
const { ValidationError, RemoteOnlineJudgeError } = global.Hydro.error;
|
||||
|
||||
async function syzoj(url, handler) {
|
||||
@@ -8,7 +9,7 @@ async function syzoj(url, handler) {
|
||||
assert(url.match(RE_SYZOJ), new ValidationError('url'));
|
||||
if (!url.endsWith('/')) url += '/';
|
||||
const [, host, pid] = RE_SYZOJ.exec(url);
|
||||
const res = await axios.get(`${url}export`);
|
||||
const res = await superagent.get(`${url}export`);
|
||||
assert(res.status === 200, new RemoteOnlineJudgeError('Cannot connect to target server'));
|
||||
assert(res.data.success, new RemoteOnlineJudgeError((res.data.error || {}).message));
|
||||
const p = res.data.obj;
|
||||
|
||||
+6
-5
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "hydrooj",
|
||||
"version": "2.3.0",
|
||||
"version": "2.4.0",
|
||||
"main": "hydro/loader.js",
|
||||
"repository": "https://github.com/hydro-dev/Hydro.git",
|
||||
"author": "masnn",
|
||||
@@ -8,7 +8,6 @@
|
||||
"dependencies": {
|
||||
"adm-zip": "^0.4.14",
|
||||
"ansi_up": "^4.0.4",
|
||||
"axios": "^0.19.0",
|
||||
"bson": "^4.0.2",
|
||||
"detect-browser": "^5.1.1",
|
||||
"eslint": "7.2.0",
|
||||
@@ -32,10 +31,12 @@
|
||||
"nodemailer": "^6.4.10",
|
||||
"nunjucks": "^3.2.1",
|
||||
"prismjs": "^1.20.0",
|
||||
"snyk": "^1.346.0",
|
||||
"sockjs": "^0.3.20",
|
||||
"superagent": "^5.2.2",
|
||||
"superagent-proxy": "^2.0.0",
|
||||
"systeminformation": "^4.26.5",
|
||||
"yargs": "^15.3.1",
|
||||
"snyk": "^1.346.0"
|
||||
"yargs": "^15.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint-config-airbnb-base": "^14.2.0",
|
||||
@@ -63,4 +64,4 @@
|
||||
]
|
||||
},
|
||||
"snyk": true
|
||||
}
|
||||
}
|
||||
@@ -709,18 +709,16 @@ async@^1.4.0:
|
||||
resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
|
||||
integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=
|
||||
|
||||
asynckit@^0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
|
||||
|
||||
atob@^2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
|
||||
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
|
||||
|
||||
axios@^0.19.0:
|
||||
version "0.19.2"
|
||||
resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27"
|
||||
integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==
|
||||
dependencies:
|
||||
follow-redirects "1.5.10"
|
||||
|
||||
balanced-match@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
|
||||
@@ -1277,6 +1275,13 @@ color-name@~1.1.4:
|
||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||
|
||||
combined-stream@^1.0.8:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
|
||||
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
|
||||
dependencies:
|
||||
delayed-stream "~1.0.0"
|
||||
|
||||
commander@^2.20.0:
|
||||
version "2.20.3"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
|
||||
@@ -1292,7 +1297,7 @@ commondir@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
|
||||
integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=
|
||||
|
||||
component-emitter@^1.2.1:
|
||||
component-emitter@^1.2.1, component-emitter@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0"
|
||||
integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==
|
||||
@@ -1363,6 +1368,11 @@ content-type@^1.0.4:
|
||||
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
|
||||
integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
|
||||
|
||||
cookiejar@^2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.2.tgz#dd8a235530752f988f9a0844f3fc589e3111125c"
|
||||
integrity sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==
|
||||
|
||||
cookies@~0.8.0:
|
||||
version "0.8.0"
|
||||
resolved "https://registry.yarnpkg.com/cookies/-/cookies-0.8.0.tgz#1293ce4b391740a8406e3c9870e828c4b54f3f90"
|
||||
@@ -1483,7 +1493,7 @@ debug@2, debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9:
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@3.1.0, debug@=3.1.0, debug@~3.1.0:
|
||||
debug@3.1.0, debug@~3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
|
||||
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
|
||||
@@ -1579,6 +1589,11 @@ degenerator@^1.0.4:
|
||||
escodegen "1.x.x"
|
||||
esprima "3.x.x"
|
||||
|
||||
delayed-stream@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
|
||||
integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
|
||||
|
||||
delegate@^3.1.2:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166"
|
||||
@@ -2129,6 +2144,11 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6:
|
||||
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
|
||||
integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
|
||||
|
||||
fast-safe-stringify@^2.0.7:
|
||||
version "2.0.7"
|
||||
resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743"
|
||||
integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==
|
||||
|
||||
faye-websocket@^0.10.0:
|
||||
version "0.10.0"
|
||||
resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4"
|
||||
@@ -2237,19 +2257,21 @@ flush-write-stream@^1.0.0:
|
||||
inherits "^2.0.3"
|
||||
readable-stream "^2.3.6"
|
||||
|
||||
follow-redirects@1.5.10:
|
||||
version "1.5.10"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a"
|
||||
integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==
|
||||
dependencies:
|
||||
debug "=3.1.0"
|
||||
|
||||
for-in@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
|
||||
integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=
|
||||
|
||||
formidable@^1.1.1:
|
||||
form-data@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.0.tgz#31b7e39c85f1355b7139ee0c647cf0de7f83c682"
|
||||
integrity sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==
|
||||
dependencies:
|
||||
asynckit "^0.4.0"
|
||||
combined-stream "^1.0.8"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
formidable@^1.1.1, formidable@^1.2.1:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.2.tgz#bf69aea2972982675f00865342b982986f6b8dd9"
|
||||
integrity sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q==
|
||||
@@ -3538,13 +3560,18 @@ mime-db@1.44.0, "mime-db@>= 1.43.0 < 2":
|
||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92"
|
||||
integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==
|
||||
|
||||
mime-types@^2.1.18, mime-types@^2.1.8, mime-types@~2.1.24:
|
||||
mime-types@^2.1.12, mime-types@^2.1.18, mime-types@^2.1.8, mime-types@~2.1.24:
|
||||
version "2.1.27"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f"
|
||||
integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==
|
||||
dependencies:
|
||||
mime-db "1.44.0"
|
||||
|
||||
mime@^2.4.4:
|
||||
version "2.4.6"
|
||||
resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.6.tgz#e5b407c90db442f2beb5b162373d07b69affa4d1"
|
||||
integrity sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==
|
||||
|
||||
mimic-fn@^1.0.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
|
||||
@@ -4314,7 +4341,7 @@ promise-inflight@^1.0.1:
|
||||
dependencies:
|
||||
asap "~2.0.3"
|
||||
|
||||
proxy-agent@^3.1.1:
|
||||
proxy-agent@3, proxy-agent@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-3.1.1.tgz#7e04e06bf36afa624a1540be247b47c970bd3014"
|
||||
integrity sha512-WudaR0eTsDx33O3EJE16PjBRZWcX8GqCEeERw1W3hZJgH/F2a46g7jty6UGty6NeJ4CKQy8ds2CJPMiyeqaTvw==
|
||||
@@ -4402,7 +4429,7 @@ pupa@^2.0.1:
|
||||
dependencies:
|
||||
escape-goat "^2.0.0"
|
||||
|
||||
qs@^6.4.0:
|
||||
qs@^6.4.0, qs@^6.9.1:
|
||||
version "6.9.4"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.4.tgz#9090b290d1f91728d3c22e54843ca44aea5ab687"
|
||||
integrity sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==
|
||||
@@ -5460,6 +5487,31 @@ strip-json-comments@~2.0.1:
|
||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
|
||||
integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
|
||||
|
||||
superagent-proxy@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/superagent-proxy/-/superagent-proxy-2.0.0.tgz#9f57515cd660e2e9ce55c0e6bd70f92eb07c3ee0"
|
||||
integrity sha512-TktJma5jPdiH1BNN+reF/RMW3b8aBTCV7KlLFV0uYcREgNf3pvo7Rdt564OcFHwkGb3mYEhHuWPBhSbOwiNaYw==
|
||||
dependencies:
|
||||
debug "^3.1.0"
|
||||
proxy-agent "3"
|
||||
|
||||
superagent@^5.2.2:
|
||||
version "5.2.2"
|
||||
resolved "https://registry.yarnpkg.com/superagent/-/superagent-5.2.2.tgz#6ff726c5642795b2c27009e92687c8e69a6bb07d"
|
||||
integrity sha512-pMWBUnIllK4ZTw7p/UaobiQPwAO5w/1NRRTDpV0FTVNmECztsxKspj3ZWEordVEaqpZtmOQJJna4yTLyC/q7PQ==
|
||||
dependencies:
|
||||
component-emitter "^1.3.0"
|
||||
cookiejar "^2.1.2"
|
||||
debug "^4.1.1"
|
||||
fast-safe-stringify "^2.0.7"
|
||||
form-data "^3.0.0"
|
||||
formidable "^1.2.1"
|
||||
methods "^1.1.2"
|
||||
mime "^2.4.4"
|
||||
qs "^6.9.1"
|
||||
readable-stream "^3.4.0"
|
||||
semver "^6.3.0"
|
||||
|
||||
supports-color@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
|
||||
|
||||
Reference in new issue
Block a user