chore: code formatting
This commit is contained in:
@@ -371,7 +371,7 @@ metadata.plugin = async function({__plugins, __templates, name, logger}) {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
})(),
|
})(),
|
||||||
]).filter(([key, value]) => (value)&&(!((name === "base")&&(key === "repositories")))),
|
]).filter(([key, value]) => (value) && (!((name === "base") && (key === "repositories")))),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
//Imports
|
//Imports
|
||||||
import octokit from "@octokit/graphql"
|
import octokit from "@octokit/graphql"
|
||||||
import OctokitRest from "@octokit/rest"
|
import OctokitRest from "@octokit/rest"
|
||||||
|
import axios from "axios"
|
||||||
import compression from "compression"
|
import compression from "compression"
|
||||||
|
import crypto from "crypto"
|
||||||
import express from "express"
|
import express from "express"
|
||||||
import ratelimit from "express-rate-limit"
|
import ratelimit from "express-rate-limit"
|
||||||
import cache from "memory-cache"
|
import cache from "memory-cache"
|
||||||
import util from "util"
|
|
||||||
import url from "url"
|
import url from "url"
|
||||||
import axios from "axios"
|
import util from "util"
|
||||||
import mocks from "../../../tests/mocks/index.mjs"
|
import mocks from "../../../tests/mocks/index.mjs"
|
||||||
import metrics from "../metrics/index.mjs"
|
import metrics from "../metrics/index.mjs"
|
||||||
import presets from "../metrics/presets.mjs"
|
import presets from "../metrics/presets.mjs"
|
||||||
import setup from "../metrics/setup.mjs"
|
import setup from "../metrics/setup.mjs"
|
||||||
import crypto from "crypto"
|
|
||||||
|
|
||||||
/**App */
|
/**App */
|
||||||
export default async function({sandbox = false} = {}) {
|
export default async function({sandbox = false} = {}) {
|
||||||
@@ -68,8 +68,9 @@ export default async function({sandbox = false} = {}) {
|
|||||||
console.debug(`metrics/app/session/${login} > authenticated with session ${session.substring(0, 6)}, using custom octokit`)
|
console.debug(`metrics/app/session/${login} > authenticated with session ${session.substring(0, 6)}, using custom octokit`)
|
||||||
return {login, graphql: octokit.graphql.defaults({headers: {authorization: `token ${token}`}}), rest: new OctokitRest.Octokit({auth: token})}
|
return {login, graphql: octokit.graphql.defaults({headers: {authorization: `token ${token}`}}), rest: new OctokitRest.Octokit({auth: token})}
|
||||||
}
|
}
|
||||||
else if (session)
|
else if (session) {
|
||||||
console.debug(`metrics/app/session > unknown session ${session.substring(0, 6)}, using default octokit`)
|
console.debug(`metrics/app/session > unknown session ${session.substring(0, 6)}, using default octokit`)
|
||||||
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,7 +147,7 @@ export default async function({sandbox = false} = {}) {
|
|||||||
//Modes and extras
|
//Modes and extras
|
||||||
app.get("/.modes", limiter, (req, res) => res.status(200).json(conf.settings.modes))
|
app.get("/.modes", limiter, (req, res) => res.status(200).json(conf.settings.modes))
|
||||||
app.get("/.extras", limiter, async (req, res) => {
|
app.get("/.extras", limiter, async (req, res) => {
|
||||||
if ((authenticated.has(req.headers["x-metrics-session"]))&&(conf.settings.extras?.logged)) {
|
if ((authenticated.has(req.headers["x-metrics-session"])) && (conf.settings.extras?.logged)) {
|
||||||
if (conf.settings.extras?.features !== true)
|
if (conf.settings.extras?.features !== true)
|
||||||
return res.status(200).json([...conf.settings.extras.features, ...conf.settings.extras.logged])
|
return res.status(200).json([...conf.settings.extras.features, ...conf.settings.extras.logged])
|
||||||
}
|
}
|
||||||
@@ -177,9 +178,9 @@ export default async function({sandbox = false} = {}) {
|
|||||||
try {
|
try {
|
||||||
const custom = uapi(req.headers["x-metrics-session"])
|
const custom = uapi(req.headers["x-metrics-session"])
|
||||||
if (custom) {
|
if (custom) {
|
||||||
const {data:{resources}} = await custom.rest.rateLimit.get()
|
const {data: {resources}} = await custom.rest.rateLimit.get()
|
||||||
if (resources)
|
if (resources)
|
||||||
return res.status(200).json({rest:resources.core, graphql:resources.graphql, search:resources.search, login:custom.login})
|
return res.status(200).json({rest: resources.core, graphql: resources.graphql, search: resources.search, login: custom.login})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch {} //eslint-disable-line no-empty
|
catch {} //eslint-disable-line no-empty
|
||||||
@@ -220,17 +221,17 @@ export default async function({sandbox = false} = {}) {
|
|||||||
console.debug(`metrics/app/oauth > request ${state}`)
|
console.debug(`metrics/app/oauth > request ${state}`)
|
||||||
//OAuth through GitHub
|
//OAuth through GitHub
|
||||||
return res.redirect(`https://github.com/login/oauth/authorize?${new url.URLSearchParams({
|
return res.redirect(`https://github.com/login/oauth/authorize?${new url.URLSearchParams({
|
||||||
client_id:conf.settings.oauth.id,
|
client_id: conf.settings.oauth.id,
|
||||||
state,
|
state,
|
||||||
redirect_uri:`${conf.settings.oauth.url}/.oauth/authorize`,
|
redirect_uri: `${conf.settings.oauth.url}/.oauth/authorize`,
|
||||||
allow_signup:false,
|
allow_signup: false,
|
||||||
scope:scopes,
|
scope: scopes,
|
||||||
})}`)
|
})}`)
|
||||||
})
|
})
|
||||||
app.get("/.oauth/authorize", async (req, res) => {
|
app.get("/.oauth/authorize", async (req, res) => {
|
||||||
//Check state
|
//Check state
|
||||||
const {code, state} = req.query
|
const {code, state} = req.query
|
||||||
if ((!state)||(!states.has(state))) {
|
if ((!state) || (!states.has(state))) {
|
||||||
console.debug("metrics/app/oauth > 400 (invalid state)")
|
console.debug("metrics/app/oauth > 400 (invalid state)")
|
||||||
return res.status(400).send("Bad request: invalid state")
|
return res.status(400).send("Bad request: invalid state")
|
||||||
}
|
}
|
||||||
@@ -238,21 +239,24 @@ export default async function({sandbox = false} = {}) {
|
|||||||
try {
|
try {
|
||||||
//Authorize user
|
//Authorize user
|
||||||
console.debug("metrics/app/oauth > authorization")
|
console.debug("metrics/app/oauth > authorization")
|
||||||
const {data} = await axios.post("https://github.com/login/oauth/access_token", `${new url.URLSearchParams({
|
const {data} = await axios.post(
|
||||||
client_id:conf.settings.oauth.id,
|
"https://github.com/login/oauth/access_token",
|
||||||
client_secret:conf.settings.oauth.secret,
|
`${new url.URLSearchParams({
|
||||||
code,
|
client_id: conf.settings.oauth.id,
|
||||||
})}`)
|
client_secret: conf.settings.oauth.secret,
|
||||||
|
code,
|
||||||
|
})}`,
|
||||||
|
)
|
||||||
const token = new url.URLSearchParams(data).get("access_token")
|
const token = new url.URLSearchParams(data).get("access_token")
|
||||||
//Validate user
|
//Validate user
|
||||||
const {data:{login}} = await axios.get("https://api.github.com/user", {headers:{Authorization:`token ${token}`}})
|
const {data: {login}} = await axios.get("https://api.github.com/user", {headers: {Authorization: `token ${token}`}})
|
||||||
console.debug(`metrics/app/oauth > authorization success for ${login}`)
|
console.debug(`metrics/app/oauth > authorization success for ${login}`)
|
||||||
const session = crypto.randomBytes(128).toString("hex")
|
const session = crypto.randomBytes(128).toString("hex")
|
||||||
authenticated.set(session, {login, token})
|
authenticated.set(session, {login, token})
|
||||||
console.debug(`metrics/app/oauth > created session ${session.substring(0, 6)}`)
|
console.debug(`metrics/app/oauth > created session ${session.substring(0, 6)}`)
|
||||||
//Redirect user back
|
//Redirect user back
|
||||||
const {from} = states.get(state)
|
const {from} = states.get(state)
|
||||||
return res.redirect(`/.oauth/redirect?${new url.URLSearchParams({to:from, session})}`)
|
return res.redirect(`/.oauth/redirect?${new url.URLSearchParams({to: from, session})}`)
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
console.debug("metrics/app/oauth > authorization failed")
|
console.debug("metrics/app/oauth > authorization failed")
|
||||||
@@ -267,7 +271,7 @@ export default async function({sandbox = false} = {}) {
|
|||||||
if (authenticated.has(session)) {
|
if (authenticated.has(session)) {
|
||||||
const {token} = authenticated.get(session)
|
const {token} = authenticated.get(session)
|
||||||
try {
|
try {
|
||||||
console.log(await axios.delete(`https://api.github.com/applications/${conf.settings.oauth.id}/grant`, {auth:{username:conf.settings.oauth.id, password:conf.settings.oauth.secret}, headers:{Accept:"application/vnd.github+json"}, data:{access_token:token}}))
|
console.log(await axios.delete(`https://api.github.com/applications/${conf.settings.oauth.id}/grant`, {auth: {username: conf.settings.oauth.id, password: conf.settings.oauth.secret}, headers: {Accept: "application/vnd.github+json"}, data: {access_token: token}}))
|
||||||
authenticated.delete(session)
|
authenticated.delete(session)
|
||||||
console.debug(`metrics/app/oauth > deleted session ${session.substring(0, 6)}`)
|
console.debug(`metrics/app/oauth > deleted session ${session.substring(0, 6)}`)
|
||||||
return res.redirect("/.oauth")
|
return res.redirect("/.oauth")
|
||||||
@@ -279,8 +283,9 @@ export default async function({sandbox = false} = {}) {
|
|||||||
app.get("/.oauth/redirect", limiter, (req, res) => res.sendFile(`${conf.paths.statics}/oauth/redirect.html`))
|
app.get("/.oauth/redirect", limiter, (req, res) => res.sendFile(`${conf.paths.statics}/oauth/redirect.html`))
|
||||||
app.get("/.oauth/enabled", limiter, (req, res) => res.json(true))
|
app.get("/.oauth/enabled", limiter, (req, res) => res.json(true))
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
app.get("/.oauth/enabled", limiter, (req, res) => res.json(false))
|
app.get("/.oauth/enabled", limiter, (req, res) => res.json(false))
|
||||||
|
}
|
||||||
|
|
||||||
//Pending requests
|
//Pending requests
|
||||||
const pending = new Map()
|
const pending = new Map()
|
||||||
@@ -405,7 +410,7 @@ export default async function({sandbox = false} = {}) {
|
|||||||
const repository = req.params.repository?.replace(/[\n\r]/g, "")
|
const repository = req.params.repository?.replace(/[\n\r]/g, "")
|
||||||
let solve = null
|
let solve = null
|
||||||
//Check username
|
//Check username
|
||||||
if ((login.startsWith("."))||(login.includes("/")))
|
if ((login.startsWith(".")) || (login.includes("/")))
|
||||||
return next()
|
return next()
|
||||||
if (!/^[-\w]+$/i.test(login)) {
|
if (!/^[-\w]+$/i.test(login)) {
|
||||||
console.debug(`metrics/app/${login} > 400 (invalid username)`)
|
console.debug(`metrics/app/${login} > 400 (invalid username)`)
|
||||||
@@ -452,9 +457,9 @@ export default async function({sandbox = false} = {}) {
|
|||||||
console.debug(`metrics/app/${login} > ${util.inspect(q, {depth: Infinity, maxStringLength: 256})}`)
|
console.debug(`metrics/app/${login} > ${util.inspect(q, {depth: Infinity, maxStringLength: 256})}`)
|
||||||
const octokit = {...api, ...uapi(req.headers["x-metrics-session"])}
|
const octokit = {...api, ...uapi(req.headers["x-metrics-session"])}
|
||||||
let uconf = conf
|
let uconf = conf
|
||||||
if ((octokit.login)&&(conf.settings.extras?.logged)&&(uconf.settings.extras?.features !== true)) {
|
if ((octokit.login) && (conf.settings.extras?.logged) && (uconf.settings.extras?.features !== true)) {
|
||||||
console.debug(`metrics/app/${login} > session is authenticated, adding additional permissions ${conf.settings.extras.logged}`)
|
console.debug(`metrics/app/${login} > session is authenticated, adding additional permissions ${conf.settings.extras.logged}`)
|
||||||
uconf = {...conf, settings:{...conf.settings, extras:{...conf.settings.extras}}}
|
uconf = {...conf, settings: {...conf.settings, extras: {...conf.settings.extras}}}
|
||||||
uconf.settings.extras.features = uconf.settings.extras.features ?? []
|
uconf.settings.extras.features = uconf.settings.extras.features ?? []
|
||||||
uconf.settings.extras.features.push(...conf.settings.extras.logged)
|
uconf.settings.extras.features.push(...conf.settings.extras.logged)
|
||||||
}
|
}
|
||||||
@@ -468,7 +473,7 @@ export default async function({sandbox = false} = {}) {
|
|||||||
const {rendered, mime} = await metrics({login, q}, {
|
const {rendered, mime} = await metrics({login, q}, {
|
||||||
...octokit,
|
...octokit,
|
||||||
plugins,
|
plugins,
|
||||||
conf:uconf,
|
conf: uconf,
|
||||||
die: q["plugins.errors.fatal"] ?? false,
|
die: q["plugins.errors.fatal"] ?? false,
|
||||||
verify: q.verify ?? false,
|
verify: q.verify ?? false,
|
||||||
convert: convert !== "auto" ? convert : null,
|
convert: convert !== "auto" ? convert : null,
|
||||||
|
|||||||
@@ -65,7 +65,7 @@
|
|||||||
computed: {
|
computed: {
|
||||||
//URL parameters
|
//URL parameters
|
||||||
params() {
|
params() {
|
||||||
return new URLSearchParams({from:location.href})
|
return new URLSearchParams({from: location.href})
|
||||||
},
|
},
|
||||||
//Is in preview mode
|
//Is in preview mode
|
||||||
preview() {
|
preview() {
|
||||||
|
|||||||
@@ -170,17 +170,17 @@
|
|||||||
computed: {
|
computed: {
|
||||||
//URL parameters
|
//URL parameters
|
||||||
params() {
|
params() {
|
||||||
return new URLSearchParams({from:location.href})
|
return new URLSearchParams({from: location.href})
|
||||||
},
|
},
|
||||||
//Unusable plugins
|
//Unusable plugins
|
||||||
unusable() {
|
unusable() {
|
||||||
const plugins = Object.entries(this.plugins.enabled).filter(([key, value]) => (value == true)&&(!this.supports(this.plugins.options.descriptions[key]))).map(([key]) => key)
|
const plugins = Object.entries(this.plugins.enabled).filter(([key, value]) => (value == true) && (!this.supports(this.plugins.options.descriptions[key]))).map(([key]) => key)
|
||||||
const options = this.edited.filter(option => !this.supports(this.plugins.options.descriptions[option]))
|
const options = this.edited.filter(option => !this.supports(this.plugins.options.descriptions[option]))
|
||||||
return [...plugins, ...options].sort()
|
return [...plugins, ...options].sort()
|
||||||
},
|
},
|
||||||
//Edited plugins options
|
//Edited plugins options
|
||||||
edited() {
|
edited() {
|
||||||
return Object.keys(this.plugins.enabled).flatMap(plugin => Object.keys(this.options({name:plugin})).filter(key => this.plugins.options[key] !== metadata[plugin]?.web[key]?.defaulted))
|
return Object.keys(this.plugins.enabled).flatMap(plugin => Object.keys(this.options({name: plugin})).filter(key => this.plugins.options[key] !== metadata[plugin]?.web[key]?.defaulted))
|
||||||
},
|
},
|
||||||
//User's avatar
|
//User's avatar
|
||||||
avatar() {
|
avatar() {
|
||||||
@@ -340,19 +340,19 @@
|
|||||||
},
|
},
|
||||||
//Get available options from plugin
|
//Get available options from plugin
|
||||||
options({name}) {
|
options({name}) {
|
||||||
return Object.fromEntries(Object.entries(this.plugins.options.descriptions).filter(([key]) => ((key.startsWith(`${name}.`))||(key === name)) && (!(key in metadata.base.web))))
|
return Object.fromEntries(Object.entries(this.plugins.options.descriptions).filter(([key]) => ((key.startsWith(`${name}.`)) || (key === name)) && (!(key in metadata.base.web))))
|
||||||
},
|
},
|
||||||
//Check if option is supported
|
//Check if option is supported
|
||||||
supports(option) {
|
supports(option) {
|
||||||
if (!option)
|
if (!option)
|
||||||
return false
|
return false
|
||||||
const {extras:required = null} = option
|
const {extras: required = null} = option
|
||||||
if (!Array.isArray(required))
|
if (!Array.isArray(required))
|
||||||
return true
|
return true
|
||||||
if (!Array.isArray(this.extras))
|
if (!Array.isArray(this.extras))
|
||||||
return this.extras
|
return this.extras
|
||||||
return required.filter(permission => !this.extras.includes(permission)).length === 0
|
return required.filter(permission => !this.extras.includes(permission)).length === 0
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
})()
|
})()
|
||||||
|
|||||||
@@ -163,7 +163,7 @@
|
|||||||
//Computed properties
|
//Computed properties
|
||||||
computed: {
|
computed: {
|
||||||
params() {
|
params() {
|
||||||
return new URLSearchParams({from:location.href})
|
return new URLSearchParams({from: location.href})
|
||||||
},
|
},
|
||||||
stats() {
|
stats() {
|
||||||
return this.metrics?.rendered.user ?? null
|
return this.metrics?.rendered.user ?? null
|
||||||
|
|||||||
@@ -55,7 +55,7 @@
|
|||||||
//Computed properties
|
//Computed properties
|
||||||
computed: {
|
computed: {
|
||||||
params() {
|
params() {
|
||||||
return new URLSearchParams({from:new URLSearchParams(location.search).get("from"), scopes:this.scopes.join(" ")})
|
return new URLSearchParams({from: new URLSearchParams(location.search).get("from"), scopes: this.scopes.join(" ")})
|
||||||
},
|
},
|
||||||
preview() {
|
preview() {
|
||||||
return /-preview$/.test(this.version)
|
return /-preview$/.test(this.version)
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
requests: {rest: {limit: 0, used: 0, remaining: 0, reset: NaN}, graphql: {limit: 0, used: 0, remaining: 0, reset: NaN}, search: {limit: 0, used: 0, remaining: 0, reset: NaN}},
|
requests: {rest: {limit: 0, used: 0, remaining: 0, reset: NaN}, graphql: {limit: 0, used: 0, remaining: 0, reset: NaN}, search: {limit: 0, used: 0, remaining: 0, reset: NaN}},
|
||||||
palette: "light",
|
palette: "light",
|
||||||
oauth: false,
|
oauth: false,
|
||||||
scopes:[],
|
scopes: [],
|
||||||
extras: [],
|
extras: [],
|
||||||
session: null,
|
session: null,
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user