This commit is contained in:
eric sciple 2020-01-24 12:20:19 -05:00
parent beb1329f9f
commit 2b95e76931
7736 changed files with 1874747 additions and 51184 deletions

View file

@ -1,41 +1,52 @@
module.exports = authenticate
module.exports = authenticate;
const { Deprecation } = require('deprecation')
const once = require('once')
const { Deprecation } = require("deprecation");
const once = require("once");
const deprecateAuthenticate = once((log, deprecation) => log.warn(deprecation))
const deprecateAuthenticate = once((log, deprecation) => log.warn(deprecation));
function authenticate (state, options) {
deprecateAuthenticate(state.octokit.log, new Deprecation('[@octokit/rest] octokit.authenticate() is deprecated. Use "auth" constructor option instead.'))
function authenticate(state, options) {
deprecateAuthenticate(
state.octokit.log,
new Deprecation(
'[@octokit/rest] octokit.authenticate() is deprecated. Use "auth" constructor option instead.'
)
);
if (!options) {
state.auth = false
return
state.auth = false;
return;
}
switch (options.type) {
case 'basic':
case "basic":
if (!options.username || !options.password) {
throw new Error('Basic authentication requires both a username and password to be set')
throw new Error(
"Basic authentication requires both a username and password to be set"
);
}
break
break;
case 'oauth':
case "oauth":
if (!options.token && !(options.key && options.secret)) {
throw new Error('OAuth2 authentication requires a token or key & secret to be set')
throw new Error(
"OAuth2 authentication requires a token or key & secret to be set"
);
}
break
break;
case 'token':
case 'app':
case "token":
case "app":
if (!options.token) {
throw new Error('Token authentication requires a token to be set')
throw new Error("Token authentication requires a token to be set");
}
break
break;
default:
throw new Error("Invalid authentication type, must be 'basic', 'oauth', 'token' or 'app'")
throw new Error(
"Invalid authentication type, must be 'basic', 'oauth', 'token' or 'app'"
);
}
state.auth = options
state.auth = options;
}

View file

@ -1,40 +1,43 @@
module.exports = authenticationBeforeRequest
module.exports = authenticationBeforeRequest;
const btoa = require('btoa-lite')
const uniq = require('lodash.uniq')
const btoa = require("btoa-lite");
const uniq = require("lodash.uniq");
function authenticationBeforeRequest (state, options) {
function authenticationBeforeRequest(state, options) {
if (!state.auth.type) {
return
return;
}
if (state.auth.type === 'basic') {
const hash = btoa(`${state.auth.username}:${state.auth.password}`)
options.headers['authorization'] = `Basic ${hash}`
return
if (state.auth.type === "basic") {
const hash = btoa(`${state.auth.username}:${state.auth.password}`);
options.headers.authorization = `Basic ${hash}`;
return;
}
if (state.auth.type === 'token') {
options.headers['authorization'] = `token ${state.auth.token}`
return
if (state.auth.type === "token") {
options.headers.authorization = `token ${state.auth.token}`;
return;
}
if (state.auth.type === 'app') {
options.headers['authorization'] = `Bearer ${state.auth.token}`
const acceptHeaders = options.headers['accept'].split(',')
.concat('application/vnd.github.machine-man-preview+json')
options.headers['accept'] = uniq(acceptHeaders).filter(Boolean).join(',')
return
if (state.auth.type === "app") {
options.headers.authorization = `Bearer ${state.auth.token}`;
const acceptHeaders = options.headers.accept
.split(",")
.concat("application/vnd.github.machine-man-preview+json");
options.headers.accept = uniq(acceptHeaders)
.filter(Boolean)
.join(",");
return;
}
options.url += options.url.indexOf('?') === -1 ? '?' : '&'
options.url += options.url.indexOf("?") === -1 ? "?" : "&";
if (state.auth.token) {
options.url += `access_token=${encodeURIComponent(state.auth.token)}`
return
options.url += `access_token=${encodeURIComponent(state.auth.token)}`;
return;
}
const key = encodeURIComponent(state.auth.key)
const secret = encodeURIComponent(state.auth.secret)
options.url += `client_id=${key}&client_secret=${secret}`
const key = encodeURIComponent(state.auth.key);
const secret = encodeURIComponent(state.auth.secret);
options.url += `client_id=${key}&client_secret=${secret}`;
}

View file

@ -1,26 +1,31 @@
module.exports = authenticationPlugin
module.exports = authenticationPlugin;
const { Deprecation } = require('deprecation')
const once = require('once')
const { Deprecation } = require("deprecation");
const once = require("once");
const deprecateAuthenticate = once((log, deprecation) => log.warn(deprecation))
const deprecateAuthenticate = once((log, deprecation) => log.warn(deprecation));
const authenticate = require('./authenticate')
const beforeRequest = require('./before-request')
const requestError = require('./request-error')
const authenticate = require("./authenticate");
const beforeRequest = require("./before-request");
const requestError = require("./request-error");
function authenticationPlugin (octokit, options) {
function authenticationPlugin(octokit, options) {
if (options.auth) {
octokit.authenticate = () => {
deprecateAuthenticate(octokit.log, new Deprecation('[@octokit/rest] octokit.authenticate() is deprecated and has no effect when "auth" option is set on Octokit constructor'))
}
return
deprecateAuthenticate(
octokit.log,
new Deprecation(
'[@octokit/rest] octokit.authenticate() is deprecated and has no effect when "auth" option is set on Octokit constructor'
)
);
};
return;
}
const state = {
octokit,
auth: false
}
octokit.authenticate = authenticate.bind(null, state)
octokit.hook.before('request', beforeRequest.bind(null, state))
octokit.hook.error('request', requestError.bind(null, state))
};
octokit.authenticate = authenticate.bind(null, state);
octokit.hook.before("request", beforeRequest.bind(null, state));
octokit.hook.error("request", requestError.bind(null, state));
}

View file

@ -1,39 +1,55 @@
module.exports = authenticationRequestError
module.exports = authenticationRequestError;
const { RequestError } = require('@octokit/request-error')
const { RequestError } = require("@octokit/request-error");
function authenticationRequestError (state, error, options) {
function authenticationRequestError(state, error, options) {
/* istanbul ignore next */
if (!error.headers) throw error
if (!error.headers) throw error;
const otpRequired = /required/.test(error.headers['x-github-otp'] || '')
const otpRequired = /required/.test(error.headers["x-github-otp"] || "");
// handle "2FA required" error only
if (error.status !== 401 || !otpRequired) {
throw error
throw error;
}
if (error.status === 401 && otpRequired && error.request && error.request.headers['x-github-otp']) {
throw new RequestError('Invalid one-time password for two-factor authentication', 401, {
headers: error.headers,
request: options
})
if (
error.status === 401 &&
otpRequired &&
error.request &&
error.request.headers["x-github-otp"]
) {
throw new RequestError(
"Invalid one-time password for two-factor authentication",
401,
{
headers: error.headers,
request: options
}
);
}
if (typeof state.auth.on2fa !== 'function') {
throw new RequestError('2FA required, but options.on2fa is not a function. See https://github.com/octokit/rest.js#authentication', 401, {
headers: error.headers,
request: options
})
if (typeof state.auth.on2fa !== "function") {
throw new RequestError(
"2FA required, but options.on2fa is not a function. See https://github.com/octokit/rest.js#authentication",
401,
{
headers: error.headers,
request: options
}
);
}
return Promise.resolve()
.then(() => {
return state.auth.on2fa()
return state.auth.on2fa();
})
.then((oneTimePassword) => {
.then(oneTimePassword => {
const newOptions = Object.assign(options, {
headers: Object.assign({ 'x-github-otp': oneTimePassword }, options.headers)
})
return state.octokit.request(newOptions)
})
headers: Object.assign(
{ "x-github-otp": oneTimePassword },
options.headers
)
});
return state.octokit.request(newOptions);
});
}