Add support for token "NOT_NEEDED" for standalone plugins (#83)
This commit is contained in:
@@ -14,7 +14,7 @@
|
|||||||
const info = (left, right, {token = false} = {}) => console.log(`${`${left}`.padEnd(56 + 9*(/0m$/.test(left)))} │ ${
|
const info = (left, right, {token = false} = {}) => console.log(`${`${left}`.padEnd(56 + 9*(/0m$/.test(left)))} │ ${
|
||||||
Array.isArray(right) ? right.join(", ") || "(none)" :
|
Array.isArray(right) ? right.join(", ") || "(none)" :
|
||||||
right === undefined ? "(default)" :
|
right === undefined ? "(default)" :
|
||||||
token ? /^MOCKED/.test(right) ? "(MOCKED TOKEN)" : (right ? "(provided)" : "(missing)") :
|
token ? /^MOCKED/.test(right) ? "(MOCKED TOKEN)" : /^NOT_NEEDED$/.test(right) ? "(NOT NEEDED)" : (right ? "(provided)" : "(missing)") :
|
||||||
typeof right === "object" ? JSON.stringify(right) :
|
typeof right === "object" ? JSON.stringify(right) :
|
||||||
right
|
right
|
||||||
}`)
|
}`)
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
|
|
||||||
//Docker image
|
//Docker image
|
||||||
if (_image)
|
if (_image)
|
||||||
info("Using prebuilt image", image)
|
info("Using prebuilt image", _image)
|
||||||
|
|
||||||
//Debug mode and flags
|
//Debug mode and flags
|
||||||
info("Debug mode", debug)
|
info("Debug mode", debug)
|
||||||
@@ -76,6 +76,7 @@
|
|||||||
info("GitHub token", token, {token:true})
|
info("GitHub token", token, {token:true})
|
||||||
if (!token)
|
if (!token)
|
||||||
throw new Error("You must provide a valid GitHub token to gather your metrics")
|
throw new Error("You must provide a valid GitHub token to gather your metrics")
|
||||||
|
conf.settings.token = token
|
||||||
const api = {}
|
const api = {}
|
||||||
api.graphql = octokit.graphql.defaults({headers:{authorization: `token ${token}`}})
|
api.graphql = octokit.graphql.defaults({headers:{authorization: `token ${token}`}})
|
||||||
info("Github GraphQL API", "ok")
|
info("Github GraphQL API", "ok")
|
||||||
@@ -179,7 +180,7 @@
|
|||||||
//Register user inputs
|
//Register user inputs
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
info.break()
|
info.break()
|
||||||
info.group({metadata, name, inputs:enabled ? inputs : {}})
|
info.group({metadata, name, inputs})
|
||||||
q[name] = true
|
q[name] = true
|
||||||
for (const [key, value] of Object.entries(inputs)) {
|
for (const [key, value] of Object.entries(inputs)) {
|
||||||
//Store token in plugin configuration
|
//Store token in plugin configuration
|
||||||
|
|||||||
@@ -193,6 +193,9 @@
|
|||||||
//Load metadata (plugins)
|
//Load metadata (plugins)
|
||||||
conf.metadata = await metadata({log})
|
conf.metadata = await metadata({log})
|
||||||
|
|
||||||
|
//Set no token property
|
||||||
|
Object.defineProperty(conf.settings, "notoken", {get() { return conf.settings.token === "NOT_NEEDED" }})
|
||||||
|
|
||||||
//Conf
|
//Conf
|
||||||
logger(`metrics/setup > setup > success`)
|
logger(`metrics/setup > setup > success`)
|
||||||
return {Templates, Plugins, conf}
|
return {Templates, Plugins, conf}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
//Tested url
|
//Tested url
|
||||||
const tested = url.match(/&url=(?<tested>.*?)(?:&|$)/)?.groups?.tested ?? faker.internet.url()
|
const tested = url.match(/&url=(?<tested>.*?)(?:&|$)/)?.groups?.tested ?? faker.internet.url()
|
||||||
//Pagespeed api
|
//Pagespeed api
|
||||||
if (/^https:..www.googleapis.com.pagespeedonline.v5/.test(url)) {
|
if (/^https:..www.googleapis.com.pagespeedonline.v5.*$/.test(url)) {
|
||||||
//Pagespeed result
|
//Pagespeed result
|
||||||
if (/v5.runPagespeed.*&key=MOCKED_TOKEN/.test(url)) {
|
if (/v5.runPagespeed.*&key=MOCKED_TOKEN/.test(url)) {
|
||||||
console.debug(`metrics/compute/mocks > mocking pagespeed api result > ${url}`)
|
console.debug(`metrics/compute/mocks > mocking pagespeed api result > ${url}`)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/** Mocked data */
|
/** Mocked data */
|
||||||
export default function ({faker, url, options, login = faker.internet.userName()}) {
|
export default function ({faker, url, options, login = faker.internet.userName()}) {
|
||||||
//Spotify api
|
//Spotify api
|
||||||
if (/^https:..api.spotify.com/.test(url)) {
|
if (/^https:..api.spotify.com.*$/.test(url)) {
|
||||||
//Get recently played tracks
|
//Get recently played tracks
|
||||||
if (/me.player.recently-played/.test(url)&&(options?.headers?.Authorization === "Bearer MOCKED_TOKEN_ACCESS")) {
|
if (/me.player.recently-played/.test(url)&&(options?.headers?.Authorization === "Bearer MOCKED_TOKEN_ACCESS")) {
|
||||||
console.debug(`metrics/compute/mocks > mocking spotify api result > ${url}`)
|
console.debug(`metrics/compute/mocks > mocking spotify api result > ${url}`)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/** Mocked data */
|
/** Mocked data */
|
||||||
export default function ({faker, url, options, login = faker.internet.userName()}) {
|
export default function ({faker, url, options, login = faker.internet.userName()}) {
|
||||||
//Twitter api
|
//Twitter api
|
||||||
if (/^https:..api.twitter.com/.test(url)) {
|
if (/^https:..api.twitter.com.*$/.test(url)) {
|
||||||
//Get user profile
|
//Get user profile
|
||||||
if ((/users.by.username/.test(url))&&(options?.headers?.Authorization === "Bearer MOCKED_TOKEN")) {
|
if ((/users.by.username/.test(url))&&(options?.headers?.Authorization === "Bearer MOCKED_TOKEN")) {
|
||||||
console.debug(`metrics/compute/mocks > mocking twitter api result > ${url}`)
|
console.debug(`metrics/compute/mocks > mocking twitter api result > ${url}`)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/** Mocked data */
|
/** Mocked data */
|
||||||
export default function ({faker, url, body, login = faker.internet.userName()}) {
|
export default function ({faker, url, body, login = faker.internet.userName()}) {
|
||||||
if (/^https:..graphql.anilist.co/.test(url)) {
|
if (/^https:..graphql.anilist.co.*$/.test(url)) {
|
||||||
//Initialization and media generator
|
//Initialization and media generator
|
||||||
const query = body.query
|
const query = body.query
|
||||||
const media = ({type}) => ({
|
const media = ({type}) => ({
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
/** Mocked data */
|
/** Mocked data */
|
||||||
export default function ({faker, url, body, login = faker.internet.userName()}) {
|
export default function ({faker, url, body, login = faker.internet.userName()}) {
|
||||||
if (/^https:..accounts.spotify.com.api.token/.test(url)) {
|
if (/^https:..accounts.spotify.com.api.token.*$/.test(url)) {
|
||||||
//Access token generator
|
//Access token generator
|
||||||
const params = new urls.URLSearchParams(body)
|
const params = new urls.URLSearchParams(body)
|
||||||
if ((params.get("grant_type") === "refresh_token")&&(params.get("client_id") === "MOCKED_CLIENT_ID")&&(params.get("client_secret") === "MOCKED_CLIENT_SECRET")&&(params.get("refresh_token") === "MOCKED_REFRESH_TOKEN")) {
|
if ((params.get("grant_type") === "refresh_token")&&(params.get("client_id") === "MOCKED_CLIENT_ID")&&(params.get("client_secret") === "MOCKED_CLIENT_SECRET")&&(params.get("refresh_token") === "MOCKED_REFRESH_TOKEN")) {
|
||||||
|
|||||||
@@ -72,8 +72,11 @@
|
|||||||
const enabled = Object.entries(metadata).map(([name]) => ({name, enabled:plugins[name]?.enabled ?? false}))
|
const enabled = Object.entries(metadata).map(([name]) => ({name, enabled:plugins[name]?.enabled ?? false}))
|
||||||
const templates = Object.entries(Templates).map(([name]) => ({name, enabled:(conf.settings.templates.enabled.length ? conf.settings.templates.enabled.includes(name) : true) ?? false}))
|
const templates = Object.entries(Templates).map(([name]) => ({name, enabled:(conf.settings.templates.enabled.length ? conf.settings.templates.enabled.includes(name) : true) ?? false}))
|
||||||
const actions = {flush:new Map()}
|
const actions = {flush:new Map()}
|
||||||
let requests = (await rest.rateLimit.get()).data.rate
|
let requests = {limit:0, used:0, remaining:0, reset:NaN}
|
||||||
setInterval(async () => requests = (await rest.rateLimit.get()).data.rate, 30*1000)
|
if (!conf.settings.notoken) {
|
||||||
|
requests = (await rest.rateLimit.get()).data.rate
|
||||||
|
setInterval(async () => requests = (await rest.rateLimit.get()).data.rate, 30*1000)
|
||||||
|
}
|
||||||
//Web
|
//Web
|
||||||
app.get("/", limiter, (req, res) => res.sendFile(`${conf.paths.statics}/index.html`))
|
app.get("/", limiter, (req, res) => res.sendFile(`${conf.paths.statics}/index.html`))
|
||||||
app.get("/index.html", limiter, (req, res) => res.sendFile(`${conf.paths.statics}/index.html`))
|
app.get("/index.html", limiter, (req, res) => res.sendFile(`${conf.paths.statics}/index.html`))
|
||||||
|
|||||||
@@ -9,6 +9,10 @@
|
|||||||
console.debug(`metrics/compute/${login}/base > started`)
|
console.debug(`metrics/compute/${login}/base > started`)
|
||||||
let {repositories, repositories_forks:forks} = imports.metadata.plugins.base.inputs({data, q, account:"bypass"}, {repositories:conf.settings.repositories ?? 100})
|
let {repositories, repositories_forks:forks} = imports.metadata.plugins.base.inputs({data, q, account:"bypass"}, {repositories:conf.settings.repositories ?? 100})
|
||||||
|
|
||||||
|
//Skip initial data gathering if not needed
|
||||||
|
if (conf.settings.notoken)
|
||||||
|
return (postprocess.skip({login, data}), {})
|
||||||
|
|
||||||
//Base parts (legacy handling for web instance)
|
//Base parts (legacy handling for web instance)
|
||||||
const defaulted = ("base" in q) ? !!q.base : true
|
const defaulted = ("base" in q) ? !!q.base : true
|
||||||
for (const part of conf.settings.plugins.base.parts)
|
for (const part of conf.settings.plugins.base.parts)
|
||||||
@@ -85,5 +89,23 @@
|
|||||||
issueComments:{totalCount:0},
|
issueComments:{totalCount:0},
|
||||||
organizations:{totalCount:0},
|
organizations:{totalCount:0},
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
//Skip base content query and instantiate an empty user instance
|
||||||
|
skip({login, data}) {
|
||||||
|
data.user = {}
|
||||||
|
for (const account of ["user", "organization"])
|
||||||
|
postprocess?.[account]({login, data})
|
||||||
|
data.account = "bypass"
|
||||||
|
Object.assign(data.user, {
|
||||||
|
databaseId:0,
|
||||||
|
name:login,
|
||||||
|
login,
|
||||||
|
createdAt:new Date(),
|
||||||
|
avatarUrl:`https://github.com/${login}.png`,
|
||||||
|
websiteUrl:null,
|
||||||
|
twitterUsername:login,
|
||||||
|
repositories:{totalCount:0, totalDiskUsage:0, nodes:[]},
|
||||||
|
packages:{totalCount:0},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -90,7 +90,7 @@
|
|||||||
computed.avatar = await avatar || "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="
|
computed.avatar = await avatar || "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="
|
||||||
|
|
||||||
//Token scopes
|
//Token scopes
|
||||||
computed.token.scopes = (await rest.request("HEAD /")).headers["x-oauth-scopes"].split(", ")
|
computed.token.scopes = conf.settings.notoken ? [] : (await rest.request("HEAD /")).headers["x-oauth-scopes"].split(", ")
|
||||||
|
|
||||||
//Meta
|
//Meta
|
||||||
data.meta = {version:conf.package.version, author:conf.package.author}
|
data.meta = {version:conf.package.version, author:conf.package.author}
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ inputs:
|
|||||||
# User account personal token
|
# User account personal token
|
||||||
# No additional scopes are needed unless you want to include private repositories metrics
|
# No additional scopes are needed unless you want to include private repositories metrics
|
||||||
# Some plugins may also require additional scopes
|
# Some plugins may also require additional scopes
|
||||||
|
# ────────────────────────────────────────────────────────────────
|
||||||
|
# If you're only using plugins which don't really require a GitHub token, you may pass "NOT_NEEDED" as value
|
||||||
token:
|
token:
|
||||||
description: GitHub Personal Token
|
description: GitHub Personal Token
|
||||||
type: token
|
type: token
|
||||||
|
|||||||
Reference in New Issue
Block a user