@@ -5,40 +5,21 @@ const log = require('./log')
|
||||
const secretIsValid = require('./sys/secret-is-valid')
|
||||
const queryString = require('query-string')
|
||||
const request = require('request')
|
||||
const autosave = require('json-autosave')
|
||||
const serverSecrets = require('./server-secrets')
|
||||
const mapKeys = require('lodash.mapkeys')
|
||||
|
||||
// This is an initial value which makes the code work while the initial data
|
||||
// is loaded. In the then() callback of scheduleAutosaving(), it's reassigned
|
||||
// with a JsonSave object.
|
||||
let githubUserTokens = { data: [] }
|
||||
const userTokenRateLimit = 12500
|
||||
|
||||
function scheduleAutosaving(githubUserTokensFile) {
|
||||
autosave(githubUserTokensFile, { data: [] })
|
||||
.then(save => {
|
||||
githubUserTokens = save
|
||||
for (let i = 0; i < githubUserTokens.data.length; i++) {
|
||||
addGithubToken(githubUserTokens.data[i])
|
||||
}
|
||||
// Personal tokens allow access to GitHub private repositories.
|
||||
// You can manage your personal GitHub token at
|
||||
// <https://github.com/settings/tokens>.
|
||||
if (serverSecrets && serverSecrets.gh_token) {
|
||||
addGithubToken(serverSecrets.gh_token)
|
||||
}
|
||||
})
|
||||
.catch(e => {
|
||||
console.error('Could not create ' + githubUserTokensFile)
|
||||
})
|
||||
}
|
||||
let githubUserTokens = []
|
||||
// Ideally, we would want priority queues here.
|
||||
const reqRemaining = new Map() // From token to requests remaining.
|
||||
const reqReset = new Map() // From token to timestamp.
|
||||
|
||||
function cancelAutosaving() {
|
||||
if (githubUserTokens.stop) {
|
||||
githubUserTokens.stop()
|
||||
githubUserTokens.save()
|
||||
githubUserTokens = { data: [] }
|
||||
}
|
||||
// Personal tokens allow access to GitHub private repositories.
|
||||
// You can manage your personal GitHub token at
|
||||
// <https://github.com/settings/tokens>.
|
||||
if (serverSecrets && serverSecrets.gh_token) {
|
||||
addGithubToken(serverSecrets.gh_token)
|
||||
}
|
||||
|
||||
function setRoutes(server) {
|
||||
@@ -166,12 +147,6 @@ function sendTokenToAllServers(token) {
|
||||
)
|
||||
}
|
||||
|
||||
// Track rate limit requests remaining.
|
||||
|
||||
// Ideally, we would want priority queues here.
|
||||
const reqRemaining = new Map() // From token to requests remaining.
|
||||
const reqReset = new Map() // From token to timestamp.
|
||||
|
||||
// token: client token as a string.
|
||||
// reqs: number of requests remaining.
|
||||
// reset: timestamp when the number of remaining requests is reset.
|
||||
@@ -189,8 +164,6 @@ function utcEpochSeconds() {
|
||||
return (Date.now() / 1000) >>> 0
|
||||
}
|
||||
|
||||
const userTokenRateLimit = 12500
|
||||
|
||||
// Return false if the token cannot reasonably be expected to perform
|
||||
// a GitHub request.
|
||||
function isTokenUsable(token, now) {
|
||||
@@ -206,7 +179,7 @@ function isTokenUsable(token, now) {
|
||||
// with a reasonable chance that the request will succeed.
|
||||
function usableTokens() {
|
||||
const now = utcEpochSeconds()
|
||||
return githubUserTokens.data.filter(function(token) {
|
||||
return githubUserTokens.filter(function(token) {
|
||||
return isTokenUsable(token, now)
|
||||
})
|
||||
}
|
||||
@@ -235,17 +208,17 @@ function addGithubToken(token) {
|
||||
// A reset date of 0 has to be in the past.
|
||||
setReqRemaining(token, userTokenRateLimit, 0)
|
||||
// Insert it only if it is not registered yet.
|
||||
if (githubUserTokens.data.indexOf(token) === -1) {
|
||||
githubUserTokens.data.push(token)
|
||||
if (githubUserTokens.indexOf(token) === -1) {
|
||||
githubUserTokens.push(token)
|
||||
}
|
||||
}
|
||||
|
||||
function rmGithubToken(token) {
|
||||
rmReqRemaining(token)
|
||||
// Remove it only if it is in there.
|
||||
const idx = githubUserTokens.data.indexOf(token)
|
||||
const idx = githubUserTokens.indexOf(token)
|
||||
if (idx >= 0) {
|
||||
githubUserTokens.data.splice(idx, 1)
|
||||
githubUserTokens.splice(idx, 1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -266,12 +239,20 @@ function sha(str) {
|
||||
.digest('hex')
|
||||
}
|
||||
|
||||
function getAllTokenIds() {
|
||||
return githubUserTokens.slice()
|
||||
}
|
||||
|
||||
function removeAllTokens() {
|
||||
githubUserTokens = []
|
||||
}
|
||||
|
||||
function serializeDebugInfo(options) {
|
||||
// Apply defaults.
|
||||
const { sanitize } = Object.assign({ sanitize: true }, options)
|
||||
|
||||
const unsanitized = {
|
||||
tokens: githubUserTokens.data,
|
||||
tokens: githubUserTokens,
|
||||
reqRemaining: mapToObject(reqRemaining),
|
||||
reqReset: mapToObject(reqReset),
|
||||
utcEpochSeconds: utcEpochSeconds(),
|
||||
@@ -347,9 +328,10 @@ function githubRequest(request, url, query, cb) {
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
scheduleAutosaving,
|
||||
cancelAutosaving,
|
||||
request: githubRequest,
|
||||
setRoutes,
|
||||
serializeDebugInfo,
|
||||
addGithubToken,
|
||||
getAllTokenIds,
|
||||
removeAllTokens,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user