node_modules ignore

This commit is contained in:
2025-05-08 23:43:47 +02:00
parent e19d52f172
commit 4574544c9f
65041 changed files with 10593536 additions and 0 deletions

62
server/node_modules/grant/lib/client.js generated vendored Normal file
View File

@@ -0,0 +1,62 @@
var compose = require('request-compose')
var oauth = require('request-oauth')
var qs = require('qs')
var pkg = require('../package')
var defaults = (args) => () => {
var {options} = compose.Request.defaults(args)()
options.headers['user-agent'] = `simov/grant/${pkg.version}`
return {options}
}
var parse = () => ({options, res, res: {headers}, body, raw}) => {
raw = body
var header = Object.keys(headers)
.find((name) => name.toLowerCase() === 'content-type')
if (/json|javascript/.test(headers[header])) {
try {
body = JSON.parse(body)
}
catch (err) {}
}
else if (/application\/x-www-form-urlencoded/.test(headers[header])) {
try {
body = qs.parse(body) // use qs instead of querystring for nested objects
}
catch (err) {}
}
// some providers return incorrect content-type like text/html or text/plain
else {
try {
body = JSON.parse(body)
}
catch (err) {
body = qs.parse(body) // use qs instead of querystring for nested objects
}
}
log({parse: {res, body}})
return {options, res, body, raw}
}
var log = (data) => {
if (process.env.DEBUG) {
try {
require('request-logs')(data)
}
catch (err) {}
}
}
module.exports = compose.extend({
Request: {defaults, oauth},
Response: {parse}
}).client

220
server/node_modules/grant/lib/config.js generated vendored Normal file
View File

@@ -0,0 +1,220 @@
var crypto = require('crypto')
var oauth = require('../config/oauth.json')
var reserved = require('../config/reserved.json')
var profile = require('../config/profile.json')
var compose = (...fns) =>
fns.reduce((x, y) => (...args) => y(x(...args)))
var dcopy = (obj) =>
JSON.parse(JSON.stringify(obj))
var merge = (...args) =>
Object.assign(...args.filter(Boolean).map(dcopy))
var filter = (obj) => Object.keys(obj)
.filter((key) =>
// empty string
obj[key] !== '' && (
// provider name
key === obj.name ||
// reserved key
reserved.includes(key)
))
.reduce((all, key) => (all[key] = obj[key], all), {})
var format = {
oauth: ({oauth}) =>
parseInt(oauth) || undefined
,
key: ({oauth, key, consumer_key, client_id}) =>
oauth === 1
? key || consumer_key
: oauth === 2
? key || client_id
: undefined
,
secret: ({oauth, secret, consumer_secret, client_secret}) =>
oauth === 1
? secret || consumer_secret
: oauth === 2
? secret || client_secret
: undefined
,
scope: ({scope, scope_delimiter = ','}) =>
scope instanceof Array
? scope.filter(Boolean).join(scope_delimiter) || undefined
: typeof scope === 'object'
? JSON.stringify(scope)
: scope || undefined
,
state: ({state}) =>
state || undefined
,
nonce: ({nonce}) =>
nonce || undefined
,
redirect_uri: ({redirect_uri, origin, prefix, protocol, host, name}) =>
redirect_uri
? redirect_uri
: origin
? `${origin}${prefix}/${name}/callback`
: protocol && host
? `${protocol}://${host}${prefix}/${name}/callback`
: undefined
,
custom_params: (provider) => {
var params = provider.custom_params || {}
// remove falsy
params = Object.keys(params)
.filter((key) => params[key])
.reduce((all, key) => (all[key] = params[key], all), {})
return Object.keys(params).length ? params : undefined
},
overrides: (provider) => {
var overrides = provider.overrides || {}
delete provider.overrides
// remove nested
Object.keys(overrides).forEach((name) => {
overrides[name] = Object.keys(overrides[name])
.filter((key) => key !== 'overrides')
.reduce((all, key) => (all[key] = overrides[name][key], all), {})
})
overrides = Object.keys(overrides)
.reduce((all, key) => (all[key] = init(provider, overrides[key]), all), {})
return Object.keys(overrides).length ? overrides : undefined
},
}
var state = (provider, key = 'state', value = provider[key]) =>
value === true || value === 'true'
? crypto.randomBytes(20).toString('hex')
: value === 'false'
? undefined
: /string|number/.test(typeof value)
? value.toString()
: undefined
var pkce = (code_verifier = crypto.randomBytes(40).toString('hex')) => ({
code_verifier,
code_challenge: crypto.createHash('sha256')
.update(code_verifier).digest().toString('base64')
.replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_')
})
var transform = (provider) => {
Object.keys(format)
.forEach((key) => provider[key] = format[key](provider))
// filter undefined
return dcopy(provider)
}
var init = compose(merge, filter, transform)
var compat = (config) =>
config.fitbit2 ? (Object.assign({}, config, {fitbit2: Object.assign({}, oauth.fitbit, profile.fitbit, config.fitbit2)})) :
config.linkedin2 ? (Object.assign({}, config, {linkedin2: Object.assign({}, oauth.linkedin, profile.linkedin, config.linkedin2)})) :
config.zeit ? (Object.assign({}, config, {zeit: Object.assign({}, oauth.vercel, profile.vercel, config.zeit)})) :
config
var defaults = ({path, prefix = '/connect', ...rest} = {}) => ({
...rest,
prefix: path ? `${path}${prefix}` : prefix
})
// init all configured providers
var ctor = ((_defaults) => (config = {}, defaults = _defaults(config.defaults)) =>
Object.keys(compat(config))
.filter((name) => !/defaults/.test(name))
.reduce((all, name) => (
all[name] = init(oauth[name], profile[name], defaults, config[name], {name, [name]: true}),
all
), {defaults})
)(defaults)
// get provider on connect
var provider = (config, session, _state = {}) => {
var name = session.provider
var provider = config[name]
if (!provider) {
if ((config.defaults || {}).dynamic !== true) {
return {}
}
provider = init(oauth[name], profile[name], config.defaults, {name, [name]: true})
}
if (session.override && provider.overrides) {
var override = provider.overrides[session.override]
if (override) {
provider = override
}
}
if ((session.dynamic && provider.dynamic) || _state.dynamic) {
var dynamic = Object.assign(
{},
_state.dynamic,
provider.dynamic === true
? session.dynamic
: Object.keys(session.dynamic || {})
.filter((key) => provider.dynamic.includes(key))
.reduce((all, key) => (all[key] = session.dynamic[key], all), {})
)
provider = init(provider, dynamic)
}
if (provider.state) {
provider = dcopy(provider)
provider.state = state(provider)
}
if (provider.nonce) {
provider = dcopy(provider)
provider.nonce = state(provider, 'nonce')
}
if (provider.pkce) {
provider = dcopy(provider)
;({
code_verifier: provider.code_verifier,
code_challenge: provider.code_challenge
} = pkce())
}
return provider
}
module.exports = Object.assign(ctor, {
compose, dcopy, merge, filter, format, state, pkce, transform, init, defaults, compat, provider
})

145
server/node_modules/grant/lib/flow/oauth1.js generated vendored Normal file
View File

@@ -0,0 +1,145 @@
var qs = require('qs')
var request = require('../client')
exports.request = ({request:client}) => async ({provider, input}) => {
var options = {
method: 'POST',
url: provider.request_url,
oauth: {
callback: provider.redirect_uri,
consumer_key: provider.key,
consumer_secret: provider.secret
}
}
if (provider.private_key) {
options.oauth.signature_method = 'RSA-SHA1'
options.oauth.private_key = provider.private_key
delete options.oauth.consumer_secret
}
if (provider.etsy || provider.linkedin) {
options.qs = {scope: provider.scope}
}
if (provider.getpocket) {
delete options.oauth
options.headers = {
'x-accept': 'application/x-www-form-urlencoded'
}
options.form = {
consumer_key: provider.key,
redirect_uri: provider.redirect_uri,
state: provider.state
}
}
if (provider.freshbooks) {
options.oauth.signature_method = 'PLAINTEXT'
}
if (provider.twitter) {
if (provider.scope) {
options.qs = {x_auth_access_type: [].concat(provider.scope).join()}
}
if (provider.custom_params) {
options.qs = {x_auth_access_type: provider.custom_params.x_auth_access_type}
}
}
if (provider.subdomain) {
options.url = options.url.replace('[subdomain]', provider.subdomain)
}
try {
var {body:output} = await request({...client, ...options})
if (provider.sellsy) {
output = qs.parse(output)
}
}
catch (err) {
var output = {error: err.body || err.message}
}
return {provider, input, output}
}
exports.authorize = async ({provider, input, output}) => {
if (!output.oauth_token && !output.code) {
output = Object.keys(output).length
? output : {error: 'Grant: OAuth1 missing oauth_token parameter'}
return {provider, input, output}
}
var url = provider.authorize_url
var params = {
oauth_token: output.oauth_token
}
if (provider.custom_params) {
for (var key in provider.custom_params) {
params[key] = provider.custom_params[key]
}
}
if (provider.flickr && provider.scope) {
params.perms = provider.scope
}
if (provider.getpocket) {
params = {
request_token: output.code,
redirect_uri: provider.redirect_uri
}
}
if (provider.ravelry || provider.trello) {
params.scope = provider.scope
}
if (provider.tripit) {
params.oauth_callback = provider.redirect_uri
}
if (provider.subdomain) {
url = url.replace('[subdomain]', provider.subdomain)
}
return {provider, input, output: `${url}?${qs.stringify(params)}`}
}
exports.access = ({request:client}) => async ({provider, input, input:{session, query}}) => {
if (!query.oauth_token && !session.request.code) {
var output = Object.keys(query).length
? query : {error: 'Grant: OAuth1 missing oauth_token parameter'}
return {provider, input, output}
}
var options = {
method: 'POST',
url: provider.access_url,
oauth: {
consumer_key: provider.key,
consumer_secret: provider.secret,
token: query.oauth_token,
token_secret: session.request.oauth_token_secret,
verifier: query.oauth_verifier
}
}
if (provider.private_key) {
options.oauth.signature_method = 'RSA-SHA1'
options.oauth.private_key = provider.private_key
delete options.oauth.consumer_secret
}
if (provider.freshbooks) {
options.oauth.signature_method = 'PLAINTEXT'
}
if (provider.getpocket) {
delete options.oauth
options.headers = {
'x-accept': 'application/x-www-form-urlencoded'
}
options.form = {
consumer_key: provider.key,
code: session.request.code
}
}
if (provider.goodreads || provider.tripit) {
delete options.oauth.verifier
}
if (provider.subdomain) {
options.url = options.url.replace('[subdomain]', provider.subdomain)
}
try {
var {body:output} = await request({...client, ...options})
}
catch (err) {
var output = {error: err.body || err.message}
}
return {provider, input, output}
}

220
server/node_modules/grant/lib/flow/oauth2.js generated vendored Normal file
View File

@@ -0,0 +1,220 @@
var crypto = require('crypto')
var qs = require('qs')
var request = require('../client')
exports.authorize = async ({provider, input}) => {
var url = provider.authorize_url
var params = {
client_id: provider.key,
response_type: 'code',
redirect_uri: provider.redirect_uri,
scope: provider.scope,
state: provider.state,
nonce: provider.nonce
}
if (provider.pkce) {
params.code_challenge_method = 'S256'
params.code_challenge = provider.code_challenge
}
if (provider.custom_params) {
for (var key in provider.custom_params) {
params[key] = provider.custom_params[key]
}
}
if (provider.basecamp) {
params.type = 'web_server'
}
if (provider.freelancer && params.scope) {
params.advanced_scopes = params.scope
delete params.scope
}
if (provider.instagram && /^\d+$/.test(provider.key)) {
params.app_id = params.client_id
delete params.client_id
params.scope = (params.scope || '').replace(/ /g, ',') || undefined
}
if (provider.optimizely && params.scope) {
params.scopes = params.scope
delete params.scope
}
if (provider.tiktok) {
params.client_key = params.client_id
delete params.client_id
}
if (provider.visualstudio) {
params.response_type = 'Assertion'
}
if (provider.wechat) {
params.appid = params.client_id
delete params.client_id
}
if (provider.subdomain) {
url = url.replace('[subdomain]', provider.subdomain)
}
var querystring = qs.stringify(params)
if (provider.unsplash && params.scope) {
var scope = params.scope
delete params.scope
querystring = qs.stringify(params) + '&scope=' + scope
}
return {provider, input, output: `${url}?${querystring}`}
}
exports.access = ({request:client}) => async ({provider, input, input:{query, body, session}}) => {
query = Object.keys(query).length ? query : body
if (!query.code) {
var output = Object.keys(query).length
? query : {error: 'Grant: OAuth2 missing code parameter'}
return {provider, input, output}
}
else if (session.state && (query.state !== session.state)) {
var output = {error: 'Grant: OAuth2 state mismatch'}
return {provider, input, output}
}
var options = {
method: 'POST',
url: provider.access_url,
form: {
grant_type: 'authorization_code',
code: query.code,
client_id: provider.key,
client_secret: provider.secret,
redirect_uri: provider.redirect_uri
}
}
if (provider.pkce) {
options.form.code_verifier = session.code_verifier
}
if (provider.basecamp) {
options.form.type = 'web_server'
}
if (provider.concur) {
delete options.form
options.qs = {
code: query.code,
client_id: provider.key,
client_secret: provider.secret
}
}
if (/autodesk|ebay|fitbit|homeaway|hootsuite|notion|reddit|trustpilot/.test(provider.name)
|| provider.token_endpoint_auth_method === 'client_secret_basic'
) {
delete options.form.client_id
delete options.form.client_secret
options.auth = {user: provider.key, pass: provider.secret}
}
if (/twitter/.test(provider.name)) {
options.form.client_id = provider.key
delete options.form.client_secret
options.auth = {user: provider.key, pass: provider.secret}
}
if (provider.token_endpoint_auth_method === 'private_key_jwt') {
var jwt = ({kid, x5t, secret}) => ({
header: {
typ: 'JWT',
alg: provider.token_endpoint_auth_signing_alg || 'RS256',
kid,
x5t
},
payload: {
iss: provider.key,
sub: provider.key,
aud: provider.access_url,
jti: crypto.randomBytes(20).toString('hex'),
exp: Math.round(Date.now() / 1000) + 300,
iat: Math.round(Date.now() / 1000) - 120,
nbf: Math.round(Date.now() / 1000) - 120
},
secret
})
var assertion = (() => {
var oidc = require('../oidc')
var {public_key, private_key} = provider
return oidc.sign(jwt({
kid: private_key.kty ? oidc.kid(private_key) : undefined,
x5t: public_key ? public_key.kty ? public_key.x5t : oidc.x5t(public_key) : undefined,
secret: private_key.kty ? oidc.pem(private_key) : private_key,
}))
})()
options.form.client_assertion_type = 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer'
options.form.client_assertion = assertion
delete options.form.client_id
delete options.form.client_secret
}
if (provider.instagram && /^\d+$/.test(provider.key)) {
options.form.app_id = options.form.client_id
delete options.form.client_id
options.form.app_secret = options.form.client_secret
delete options.form.client_secret
}
if (provider.notion) {
options.json = options.form
delete options.form
}
if (provider.tiktok) {
options.form.client_key = options.form.client_id
delete options.form.client_id
}
if (provider.qq) {
options.method = 'GET'
options.qs = options.form
delete options.form
}
if (provider.untappd) {
options.method = 'GET'
options.qs = options.form
delete options.qs.grant_type
options.qs.response_type = 'code'
delete options.form
}
if (provider.wechat) {
options.method = 'GET'
options.qs = options.form
delete options.form
options.qs.appid = options.qs.client_id
options.qs.secret = options.qs.client_secret
delete options.qs.client_id
delete options.qs.client_secret
}
if (provider.smartsheet) {
delete options.form.client_secret
var hash = crypto.createHash('sha256')
hash.update(provider.secret + '|' + query.code)
options.form.hash = hash.digest('hex')
}
if (provider.surveymonkey) {
options.qs = {api_key: provider.custom_params.api_key}
}
if (provider.visualstudio) {
options.form = {
client_assertion_type: 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
client_assertion: provider.secret,
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
assertion: query.code,
redirect_uri: provider.redirect_uri
}
}
if (provider.withings) {
options.form.action = 'requesttoken'
}
if (provider.subdomain) {
options.url = options.url.replace('[subdomain]', provider.subdomain)
}
try {
var {body:output} = await request({...client, ...options})
if (provider.intuit) {
output.realmId = query.realmId
}
if (provider.withings) {
output = output.body
}
}
catch (err) {
var output = {error: err.body || err.message}
}
return {provider, input, output}
}

31
server/node_modules/grant/lib/grant.js generated vendored Normal file
View File

@@ -0,0 +1,31 @@
var {compose} = require('./util')
var {defaults, connect, callback} = require('./request')
var {data, transport} = require('./response')
var _config = require('./config')
module.exports = ({config, request, state, extend}) => {
config = _config(config)
if (!extend) {
extend = [require('./profile')]
}
var pipe = compose(
defaults(config),
({provider, input, input:{params}}) => params.override !== 'callback'
? connect({request})({provider, input})
: compose(
callback({request})({provider, input}),
data,
extend ? compose(...extend.map((fn) => fn({request, state}))) : (args) => ({...args})
)({provider, input}),
transport,
)
pipe.config = config
return pipe
}

89
server/node_modules/grant/lib/handler/aws.js generated vendored Normal file
View File

@@ -0,0 +1,89 @@
var qs = require('qs')
var Grant = require('../grant')
var Session = require('../session')
module.exports = function (args = {}) {
var grant = Grant(args.config ? args : {config: args})
app.config = grant.config
var regex = new RegExp([
'^',
app.config.defaults.prefix,
/(?:\/([^\/\?]+?))/.source, // /:provider
/(?:\/([^\/\?]+?))?/.source, // /:override?
/(?:\/$|\/?\?+.*)?$/.source, // querystring
].join(''), 'i')
var store = Session(args.session)
async function app (event, state) {
var req = params(event)
var session = store(req)
var match = regex.exec(req.path)
if (!match) {
return {session}
}
var {location, session:sess, state} = await grant({
method: req.method,
params: {provider: match[1], override: match[2]},
query: req.query,
body: req.body,
state,
session: (await session.get()).grant
})
await session.set({grant: sess})
return location
? {session, redirect: redirect(event, location, session)}
: {session, response: state.response || sess.response}
}
return app
}
var path = ({version, path, rawPath, requestContext:ctx} = event) =>
version === '2.0' ? rawPath :
version === '1.0' ? path : ctx.path
var body = ({body, isBase64Encoded} = event) =>
body
? isBase64Encoded ? Buffer.from(body, 'base64').toString()
: body : {}
var params = (event) =>
!event.version || event.version === '1.0' ?
{
method: event.httpMethod,
path: path(event),
query: qs.parse(event.queryStringParameters),
headers: event.headers,
body: qs.parse(body(event)),
}
: event.version === '2.0' ?
{
method: event.requestContext.http.method,
path: path(event),
query: qs.parse(event.rawQueryString),
headers: {...event.headers, Cookie: (event.cookies || []).join('; ')},
body: qs.parse(body(event)),
}
: {}
var redirect = (event, location, session) =>
!event.version || event.version === '1.0' ?
{
statusCode: 302,
headers: {location},
multiValueHeaders: {'set-cookie': session.headers['set-cookie']}
}
: event.version === '2.0' ?
{
statusCode: 302,
headers: {location},
cookies: session.headers['set-cookie']
}
: {}

53
server/node_modules/grant/lib/handler/azure.js generated vendored Normal file
View File

@@ -0,0 +1,53 @@
var qs = require('qs')
var Grant = require('../grant')
var Session = require('../session')
module.exports = function (args = {}) {
var grant = Grant(args.config ? args : {config: args})
app.config = grant.config
var regex = new RegExp([
/^https?:\/\/[^/]+/.source,
app.config.defaults.prefix,
/(?:\/([^\/\?]+?))/.source, // /:provider
/(?:\/([^\/\?]+?))?/.source, // /:override?
/(?:\/$|\/?\?+.*)?$/.source, // querystring
].join(''), 'i')
var store = Session(args.session)
async function app (req, state) {
var session = store(req)
var match = regex.exec(req.originalUrl)
if (!match) {
return {session}
}
var {location, session:sess, state} = await grant({
method: req.method,
params: {provider: match[1], override: match[2]},
query: {...req.query, code: req.query.oauth_code},
body: req.method === 'POST' ? req.body : {},
state,
session: (await session.get()).grant
})
await session.set({grant: sess})
return location
? {session, redirect: redirect(location, session)}
: {session, response: state.response || sess.response}
}
return app
}
var redirect = (location, session) => ({
status: 302,
headers: {
location,
'set-cookie': session.headers['set-cookie']
}
})

46
server/node_modules/grant/lib/handler/curveball.js generated vendored Normal file
View File

@@ -0,0 +1,46 @@
var qs = require('qs')
var Grant = require('../grant')
module.exports = function (args = {}) {
var grant = Grant(args.config ? args : {config: args})
app.config = grant.config
var regex = new RegExp([
'^',
app.config.defaults.prefix,
/(?:\/([^\/\?]+?))/.source, // /:provider
/(?:\/([^\/\?]+?))?/.source, // /:override?
/(?:\/$|\/?\?+.*)?$/.source, // querystring
].join(''), 'i')
async function app (ctx, next) {
var match = regex.exec(ctx.path)
if (!match) {
return next()
}
if (!ctx.state.session) {
throw new Error('Grant: mount session middleware first')
}
if (ctx.method === 'POST' && !ctx.request.body) {
throw new Error('Grant: mount body parser middleware first')
}
var {location, session, state} = await grant({
method: ctx.method,
params: {provider: match[1], override: match[2]},
query: qs.parse(ctx.request.query),
body: qs.parse(ctx.request.body),
state: ctx.state.grant,
session: ctx.state.session.grant,
})
ctx.state.session.grant = session
ctx.state.grant = state
location ? ctx.response.redirect(302, location) : await next()
}
return app
}

53
server/node_modules/grant/lib/handler/express-4.js generated vendored Normal file
View File

@@ -0,0 +1,53 @@
var Grant = require('../grant')
module.exports = function (args = {}) {
var grant = Grant(args.config ? args : {config: args})
app.config = grant.config
var regex = new RegExp([
'^',
app.config.defaults.prefix,
/(?:\/([^\/\?]+?))/.source, // /:provider
/(?:\/([^\/\?]+?))?/.source, // /:override?
/(?:\/$|\/?\?+.*)?$/.source, // querystring
].join(''), 'i')
async function app (req, res, next) {
var match = regex.exec(req.originalUrl)
if (!match) {
return next()
}
if (!req.session) {
next(new Error('Grant: mount session middleware first'))
return
}
if (req.method === 'POST' && !req.body) {
next(new Error('Grant: mount body parser middleware first'))
return
}
var {location, session, state} = await grant({
method: req.method,
params: {provider: match[1], override: match[2]},
query: req.query,
body: req.body,
state: res.locals.grant,
session: req.session.grant,
})
req.session.grant = session
res.locals.grant = state
location ? redirect(req, res, location) : next()
}
return app
}
var redirect = (req, res, location) =>
typeof req.session.save === 'function' &&
Object.getPrototypeOf(req.session).save.length
? req.session.save(() => res.redirect(location))
: res.redirect(location)

50
server/node_modules/grant/lib/handler/fastify.js generated vendored Normal file
View File

@@ -0,0 +1,50 @@
var qs = require('qs')
var Grant = require('../grant')
module.exports = function (args = {}) {
function app (server, options, next) {
args = args.config ? args : {config: args}
var grant = Grant(args)
app.config = grant.config
var prefix = app.config.defaults.prefix.replace(options.prefix, '')
server.route({
method: ['GET', 'POST'],
path: `${prefix}/:provider`,
handler
})
server.route({
method: ['GET', 'POST'],
path: `${prefix}/:provider/:override`,
handler
})
async function handler (req, res) {
if (!req.session) {
throw new Error('Grant: register session plugin first')
}
var {location, session, state} = await grant({
method: req.method,
params: req.params,
query: qs.parse(req.query),
body: qs.parse(req.body),
state: req.grant,
session: req.session.grant,
})
req.session.grant = session
res.grant = state
return location ? res.redirect(location) : res.send()
}
next()
}
return app
}

56
server/node_modules/grant/lib/handler/gcloud.js generated vendored Normal file
View File

@@ -0,0 +1,56 @@
var qs = require('qs')
var Grant = require('../grant')
var Session = require('../session')
module.exports = function (args = {}) {
var grant = Grant(args.config ? args : {config: args})
app.config = grant.config
var regex = new RegExp([
'^',
app.config.defaults.prefix,
/(?:\/([^\/\?]+?))/.source, // /:provider
/(?:\/([^\/\?]+?))?/.source, // /:override?
/(?:\/$|\/?\?+.*)?$/.source, // querystring
].join(''), 'i')
var store = Session(args.session)
async function app (req, res, state) {
var session = store(req, res)
var match = regex.exec(req.url)
if (!match) {
return {session}
}
var {location, session:sess, state} = await grant({
method: req.method,
params: {provider: match[1], override: match[2]},
query: qs.parse(req.query),
body: req.body,
state,
session: (await session.get()).grant
})
await session.set({grant: sess})
return location
? (redirect(res, location, session), {session, redirect: true})
: {session, response: state.response || sess.response}
}
return app
}
var redirect = (res, location, session) => {
res.setHeader('set-cookie', session.headers['set-cookie'])
setImmediate(() => {
if (!res.headersSent) {
res.statusCode = 302
res.setHeader('location', location)
res.end()
}
})
}

60
server/node_modules/grant/lib/handler/hapi-16.js generated vendored Normal file
View File

@@ -0,0 +1,60 @@
var url = require('url')
var qs = require('qs')
var Grant = require('../grant')
module.exports = function (args = {}) {
var app = {}
function register (server, options, next) {
args = args.config ? args : {config: args}
args.config = Object.keys(options).length ? options : args.config
var grant = Grant(args)
app.config = grant.config
var prefix = app.config.defaults.prefix
.replace(server.realm.modifiers.route.prefix, '')
server.route({
method: ['GET', 'POST'],
path: `${prefix}/{provider}/{override?}`,
handler: (req, res) => {
if (!(req.session || req.yar)) {
throw new Error('Grant: register session plugin first')
}
var query = (parseInt(server.version.split('.')[0]) >= 12)
? qs.parse(url.parse(req.url, false).query) // #2985
: req.query
var body = (parseInt(server.version.split('.')[0]) >= 12)
? qs.parse(req.payload) // #2985
: req.payload
grant({
method: req.method,
params: req.params,
query: query,
body: body,
state: req.plugins.grant,
session: (req.session || req.yar).get('grant'),
}).then(({location, session, state}) => {
;(req.session || req.yar).set('grant', session)
req.plugins.grant = state
location ? res.redirect(location) : res.continue()
})
}
})
next()
}
register.attributes = {
pkg: require('../../package.json')
}
app.register = register
return app
}

47
server/node_modules/grant/lib/handler/hapi-17.js generated vendored Normal file
View File

@@ -0,0 +1,47 @@
var qs = require('qs')
var Grant = require('../grant')
module.exports = function (args = {}) {
var app = {}
function register (server, options) {
args = args.config ? args : {config: args}
args.config = Object.keys(options).length ? options : args.config
var grant = Grant(args)
app.config = grant.config
var prefix = app.config.defaults.prefix
.replace(server.realm.modifiers.route.prefix, '')
server.route({
method: ['GET', 'POST'],
path: `${prefix}/{provider}/{override?}`,
handler: async (req, res) => {
if (!req.yar) {
throw new Error('Grant: register session plugin first')
}
var {location, session, state} = await grant({
method: req.method,
params: req.params,
query: qs.parse(req.query),
body: qs.parse(req.payload), // #2985
state: req.plugins.grant,
session: req.yar.get('grant'),
})
req.yar.set('grant', session)
req.plugins.grant = state
return location ? res.redirect(location) : res.continue
}
})
}
app.pkg = require('../../package.json')
app.register = register
return app
}

46
server/node_modules/grant/lib/handler/koa-1.js generated vendored Normal file
View File

@@ -0,0 +1,46 @@
var qs = require('qs')
var Grant = require('../grant')
module.exports = function (args) {
var grant = Grant((args || {}).config ? args : {config: args})
app.config = grant.config
var regex = new RegExp([
'^',
app.config.defaults.prefix,
/(?:\/([^\/\?]+?))/.source, // /:provider
/(?:\/([^\/\?]+?))?/.source, // /:override?
/(?:\/$|\/?\?+.*)?$/.source, // querystring
].join(''), 'i')
function* app (next) {
var match = regex.exec(this.request.originalUrl)
if (!match) {
return yield next
}
if (!this.session) {
throw new Error('Grant: mount session middleware first')
}
if (this.method === 'POST' && !this.request.body) {
throw new Error('Grant: mount body parser middleware first')
}
var result = yield grant({
method: this.method,
params: {provider: match[1], override: match[2]},
query: qs.parse(this.request.query),
body: this.request.body,
state: this.state.grant,
session: this.session.grant,
})
this.session.grant = result.session
this.state.grant = result.state
result.location ? this.response.redirect(result.location) : yield next
}
return app
}

46
server/node_modules/grant/lib/handler/koa-2.js generated vendored Normal file
View File

@@ -0,0 +1,46 @@
var qs = require('qs')
var Grant = require('../grant')
module.exports = function (args = {}) {
var grant = Grant(args.config ? args : {config: args})
app.config = grant.config
var regex = new RegExp([
'^',
app.config.defaults.prefix,
/(?:\/([^\/\?]+?))/.source, // /:provider
/(?:\/([^\/\?]+?))?/.source, // /:override?
/(?:\/$|\/?\?+.*)?$/.source, // querystring
].join(''), 'i')
async function app (ctx, next) {
var match = regex.exec(ctx.originalUrl)
if (!match) {
return next()
}
if (!ctx.session) {
ctx.throw(400, 'Grant: mount session middleware first')
}
if (ctx.method === 'POST' && !ctx.request.body) {
ctx.throw(400, 'Grant: mount body parser middleware first')
}
var {location, session, state} = await grant({
method: ctx.method,
params: {provider: match[1], override: match[2]},
query: qs.parse(ctx.request.query),
body: ctx.request.body,
state: ctx.state.grant,
session: ctx.session.grant,
})
ctx.session.grant = session
ctx.state.grant = state
location ? ctx.response.redirect(location) : await next()
}
return app
}

62
server/node_modules/grant/lib/handler/node.js generated vendored Normal file
View File

@@ -0,0 +1,62 @@
var qs = require('qs')
var Grant = require('../grant')
var Session = require('../session')
module.exports = function (args = {}) {
var grant = Grant(args.config ? args : {config: args})
app.config = grant.config
var regex = new RegExp([
'^',
app.config.defaults.prefix,
/(?:\/([^\/\?]+?))/.source, // /:provider
/(?:\/([^\/\?]+?))?/.source, // /:override?
/(?:\/$|\/?\?+(.*))?$/.source, // querystring
].join(''), 'i')
var store = Session(args.session)
async function app (req, res, state) {
var session = store(req, res)
var match = regex.exec(req.url)
if (!match) {
return {session}
}
var {location, session:sess, state} = await grant({
method: req.method,
params: {provider: match[1], override: match[2]},
query: qs.parse(match[3]),
body: req.method === 'POST' ? qs.parse(await buffer(req)) : {},
state,
session: (await session.get()).grant
})
await session.set({grant: sess})
return location
? (redirect(res, location, session), {session, redirect: true})
: {session, response: state.response || sess.response}
}
return app
}
var redirect = (res, location, session) => {
res.setHeader('set-cookie', session.headers['set-cookie'])
setImmediate(() => {
if (!res.headersSent) {
res.statusCode = 302
res.setHeader('location', location)
res.end()
}
})
}
var buffer = (req, body = []) => new Promise((resolve, reject) => req
.on('data', (chunk) => body.push(chunk))
.on('end', () => resolve(Buffer.concat(body).toString('utf8')))
.on('error', reject)
)

56
server/node_modules/grant/lib/handler/vercel.js generated vendored Normal file
View File

@@ -0,0 +1,56 @@
var qs = require('qs')
var Grant = require('../grant')
var Session = require('../session')
module.exports = function (args = {}) {
var grant = Grant(args.config ? args : {config: args})
app.config = grant.config
var regex = new RegExp([
'^',
app.config.defaults.prefix,
/(?:\/([^\/\?]+?))/.source, // /:provider
/(?:\/([^\/\?]+?))?/.source, // /:override?
/(?:\/$|\/?\?+.*)?$/.source, // querystring
].join(''), 'i')
var store = Session(args.session)
async function app (req, res, state) {
var session = store(req, res)
var match = regex.exec(req.url)
if (!match) {
return {session}
}
var {location, session:sess, state} = await grant({
method: req.method,
params: {provider: match[1], override: match[2]},
query: qs.parse(req.query),
body: req.body,
state,
session: (await session.get()).grant
})
await session.set({grant: sess})
return location
? (redirect(res, location, session), {session, redirect: true})
: {session, response: state.response || sess.response}
}
return app
}
var redirect = (res, location, session) => {
res.setHeader('set-cookie', session.headers['set-cookie'])
setImmediate(() => {
if (!res.headersSent) {
res.statusCode = 302
res.setHeader('location', location)
res.end()
}
})
}

47
server/node_modules/grant/lib/oidc.js generated vendored Normal file
View File

@@ -0,0 +1,47 @@
var crypto = require('crypto')
var base64url = (str) =>
str.toString('base64').replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_')
var kid = (jwk) => {
if (jwk.kid) {
return jwk.kid
}
var keys =
jwk.kty === 'RSA' ? {e: jwk.e, kty: jwk.kty, n: jwk.n} :
jwk.kty === 'EC' ? {crv: jwk.crv, kty: jwk.kty, x: jwk.x, y: jwk.y} :
jwk.kty === 'oct' ? {k: jwk.k, kty: jwk.kty} : undefined
return keys
? base64url(crypto.createHash('sha256').update(JSON.stringify(keys)).digest())
: undefined
}
var x5t = (cert) => {
var s1 = cert.replace(/(?:-----(?:BEGIN|END) CERTIFICATE-----|\s)/g, '')
var s2 = Buffer.from(s1, 'base64')
var s3 = crypto.createHash('sha1').update(s2).digest('hex').toUpperCase()
return base64url(Buffer.from(s3, 'hex'))
}
var pem = (jwk) => {
var pem = require('jwk-to-pem')
return pem(jwk, {private: true})
}
var sign = (jwt) => {
var jws = require('jws')
return jws.sign(jwt)
}
var jwt = (str) => {
var [header, payload, signature] = str.split('.')
return {
header: JSON.parse(Buffer.from(header, 'base64').toString('binary')),
payload: JSON.parse(Buffer.from(payload, 'base64').toString('utf8')),
signature,
}
}
module.exports = {base64url, kid, x5t, pem, sign, jwt}

102
server/node_modules/grant/lib/profile.js generated vendored Normal file
View File

@@ -0,0 +1,102 @@
var request = require('./client')
module.exports = ({request:client}) => async ({provider, input, output}) => {
if (!provider.response || !provider.response.includes('profile')) {
return {provider, input, output}
}
if (provider.apple && !provider.profile_url && input.body.user) {
output.profile = input.body.user
return {provider, input, output}
}
if (!provider.profile_url) {
output.profile = {error: 'Grant: No profile URL found!'}
return {provider, input, output}
}
var options = {
method: 'GET',
url: provider.profile_url,
headers: {},
}
if (provider.oauth === 2) {
options.headers.authorization = `Bearer ${output.access_token}`
}
else if (provider.oauth === 1) {
options.oauth = {
consumer_key: provider.key,
consumer_secret: provider.secret,
token: output.access_token,
token_secret: output.access_secret,
}
}
if (custom[provider.name]) {
Object.assign(options, custom[provider.name]({provider, output}))
}
if (provider.subdomain) {
options.url = options.url.replace('[subdomain]', provider.subdomain)
}
try {
var {body} = await request({...client, ...options})
// JSONP
if (provider.flickr) {
body = JSON.parse(/^.*\((.*)\)/.exec(body)[1])
}
// JSONP + secondary request
if (provider.qq) {
body = JSON.parse(/^.*\((.*)\)/.exec(Object.keys(body)[0])[1])
body = {...body, ...(await request({...client, ...options,
url: 'https://graph.qq.com/user/get_user_info',
qs: {
access_token: output.access_token,
oauth_consumer_key: provider.key,
openid: body.openid
}
})).body}
}
output.profile = body
}
catch (err) {
output.profile = {error: err.body || err.message}
}
return {provider, input, output}
}
var custom = {
arcgis: () => ({qs: {f: 'json'}}),
baidu: ({output}) => ({qs: {access_token: output.access_token}}),
constantcontact: ({provider}) => ({qs: {api_key: provider.key}}),
deezer: ({output}) => ({qs: {access_token: output.access_token}}),
disqus: ({provider}) => ({qs: {api_key: provider.key}}),
dropbox: () => ({method: 'POST'}),
echosign: ({output}) => ({headers: {'Access-Token': output.access_token}}),
flickr: ({provider}) => ({qs: {method: 'flickr.urls.getUserProfile', api_key: provider.key, format: 'json'}}),
foursquare: ({output}) => ({qs: {oauth_token: output.access_token}}),
getpocket: ({provider, output}) => ({json: {consumer_key: provider.key, access_token: output.access_token}}),
instagram: ({provider, output}) => /^\d+$/.test(provider.key) ? {qs: {fields: 'id,account_type,username'}} : {url: 'https://api.instagram.com/v1/users/self', qs: {access_token: output.access_token}},
mailchimp: ({output}) => ({qs: {apikey: output.access_token}}),
meetup: ({output}) => ({qs: {member_id: 'self'}}),
mixcloud: ({output}) => ({qs: {access_token: output.access_token}}),
qq: ({output}) => ({qs: {access_token: output.access_token}}),
shopify: ({output}) => ({headers: {'X-Shopify-Access-Token': output.access_token}}),
slack: ({output}) => ({qs: {token: output.access_token}}),
soundcloud: ({output}) => ({qs: {oauth_token: output.access_token}}),
stackexchange: ({output}) => ({qs: {key: output.access_token}}),
stocktwits: ({output}) => ({qs: {access_token: output.access_token}}),
tiktok: ({output}) => ({method: 'POST', json: {access_token: output.access_token, open_id: output.raw.open_id, fields: ['open_id', 'union_id', 'avatar_url', 'display_name']}}),
tumblr: ({output}) => ({qs: {api_key: output.access_token}}),
vk: ({output}) => ({qs: {access_token: output.access_token, v: '5.103'}}),
wechat: ({output}) => ({qs: {access_token: output.access_token, openid: output.raw.openid, lang: 'zh_CN'}}),
weibo: ({output}) => ({qs: {access_token: output.access_token, uid: output.raw.uid}}),
twitch: ({provider, output}) => ({headers: {'client-id': provider.key, authorization: `Bearer ${output.access_token}`}}),
twitter: ({output}) => ({qs: {user_id: output.raw.user_id}}),
}

69
server/node_modules/grant/lib/request.js generated vendored Normal file
View File

@@ -0,0 +1,69 @@
var {compose, dcopy} = require('./util')
var _config = require('./config')
var oauth1 = require('./flow/oauth1')
var oauth2 = require('./flow/oauth2')
var defaults = (config) => ({method, params, query, body, state, session}) => {
method = method.toUpperCase()
params = dcopy(params || {})
query = dcopy(query || {})
body = dcopy(body || {})
state = dcopy(state || {})
session = dcopy(params.override === 'callback' ? (session || {}) : {})
if (params.override !== 'callback') {
session.provider = params.provider
if (params.override) {
session.override = params.override
}
if (method === 'GET' && Object.keys(query).length) {
session.dynamic = query
}
else if (method === 'POST' && Object.keys(body).length) {
session.dynamic = body
}
}
var provider = _config.provider(config, session, state)
return {provider, input: {method, params, query, body, state, session}}
}
var connect = ({request}) => ({provider, input, input:{session}, output}) =>
provider.oauth === 1
? compose(
oauth1.request({request}),
({provider, input, input:{session}, output}) => (
session.request = output,
oauth1.authorize({provider, input, output})
)
)({provider, input})
: provider.oauth === 2
? (
session.state = provider.state,
session.nonce = provider.nonce,
session.code_verifier = provider.code_verifier,
oauth2.authorize({provider, input})
)
: (
output = {error: 'Grant: missing or misconfigured provider'},
{provider, input, output}
)
var callback = ({request}) => ({provider, input, output}) =>
provider.oauth === 1
? oauth1.access({request})
: provider.oauth === 2
? oauth2.access({request})
: ({provider, input, output}) => (
output = {error: 'Grant: missing session or misconfigured provider'},
{provider, input, output}
)
module.exports = {defaults, connect, callback}

124
server/node_modules/grant/lib/response.js generated vendored Normal file
View File

@@ -0,0 +1,124 @@
var qs = require('qs')
var tokens = (provider, response) => {
var data = {}
if (provider.concur) {
data.access_token = response.replace(
/[\s\S]+<Token>([^<]+)<\/Token>[\s\S]+/, '$1')
data.refresh_token = response.replace(
/[\s\S]+<Refresh_Token>([^<]+)<\/Refresh_Token>[\s\S]+/, '$1')
}
else if (provider.getpocket) {
data.access_token = response.access_token
}
else if (provider.yammer) {
data.access_token = response.access_token.token
}
else if (provider.oauth === 1) {
if (response.oauth_token) {
data.access_token = response.oauth_token
}
if (response.oauth_token_secret) {
data.access_secret = response.oauth_token_secret
}
}
else if (provider.oauth === 2) {
if (response.id_token) {
data.id_token = response.id_token
}
if (response.access_token) {
data.access_token = response.access_token
}
if (response.refresh_token) {
data.refresh_token = response.refresh_token
}
}
return data
}
var oidc = (provider, session, response) => {
if (!/^[a-zA-Z0-9\-_]+?\.[a-zA-Z0-9\-_]+?\.([a-zA-Z0-9\-_]+)?$/.test(response.id_token)) {
return {error: 'Grant: OpenID Connect invalid id_token format'}
}
var [header, payload, signature] = response.id_token.split('.')
try {
header = JSON.parse(Buffer.from(header, 'base64').toString('binary'))
payload = JSON.parse(Buffer.from(payload, 'base64').toString('utf8'))
}
catch (err) {
return {error: 'Grant: OpenID Connect error decoding id_token'}
}
if (![].concat(payload.aud).includes(provider.key)) {
return {error: 'Grant: OpenID Connect invalid id_token audience'}
}
else if (session.nonce && (payload.nonce !== session.nonce)) {
return {error: 'Grant: OpenID Connect nonce mismatch'}
}
return {header, payload, signature}
}
var data = ({provider, input, input:{session}, output}) => {
if (output.error) {
return {provider, input, output}
}
if (output.id_token) {
var jwt = oidc(provider, session, output)
if (jwt.error) {
return {provider, input, output: jwt}
}
}
if (!provider.response) {
var data = tokens(provider, output)
data.raw = output
}
else {
var data = {}
var response = [].concat(provider.response)
if (response.find((key) => /token/.test(key))) {
data = tokens(provider, output)
}
if (response.includes('jwt') && jwt) {
data.jwt = {id_token: jwt}
}
if (response.includes('raw')) {
data.raw = output
}
}
return {provider, input, output: data}
}
var transport = ({provider, input, input:{params, state, session}, output}) => ({
location:
(params.override !== 'callback' && !output.error)
? output
: (!provider.transport || provider.transport === 'querystring')
? `${provider.callback || '/'}?${qs.stringify(output)}`
: provider.transport === 'session'
? provider.callback
: undefined,
session: (
provider.transport === 'session' ? session.response = output : null,
session
),
state: (
provider.transport === 'state' ? state.response = output : null,
state
),
})
module.exports = {data, transport}

106
server/node_modules/grant/lib/session.js generated vendored Normal file
View File

@@ -0,0 +1,106 @@
var crypto = require('crypto')
var cookie = require('cookie')
var signature = require('cookie-signature')
module.exports = ({name, secret, cookie:options, store}) => {
name = name || 'grant'
options = options || {path: '/', httpOnly: true, secure: false, maxAge: null}
if (!secret) {
throw new Error('Grant: cookie secret is required')
}
var embed = !store
return (req) => {
var headers = Object.keys(req.headers)
.filter((key) => /(?:set-)?cookie/i.test(key))
.reduce((all, key) => (all[key.toLowerCase()] = req.headers[key], all), {})
headers['set-cookie'] =
headers['set-cookie'] ||
(req.multiValueHeaders && req.multiValueHeaders['Set-Cookie']) ||
[]
var cookies = {
input:
// vercel - parsed object
typeof req.cookies === 'object' && !(req.cookies instanceof Array) ? req.cookies :
cookie.parse(
headers.cookie ? headers.cookie :
// aws v2 event - array of key=value pairs
req.cookies ? req.cookies.join('; ') :
''
),
output: headers['set-cookie'].reduce((all, str) =>
(all[str.split(';')[0].split('=')[0]] = str, all), {})
}
var encode = (payload, opt = {}) => {
var data = embed
? Buffer.from(JSON.stringify(payload)).toString('base64')
: payload
var value = signature.sign(data, secret)
var output = cookie.serialize(name, value, {...options, ...opt})
cookies.output[name] = output
headers['set-cookie'] = Object.keys(cookies.output)
.map((name) => cookies.output[name])
}
var cookieStore = () => {
var session = (() => {
var payload = signature.unsign(cookies.input[name] || '', secret)
try {
return JSON.parse(Buffer.from(payload, 'base64').toString())
}
catch (err) {
return {grant: {}}
}
})()
var store = {
get: async (sid) => session,
set: async (sid, value) => session = value,
remove: async (sid) => session = {}
}
return {
get: async () => {
return store.get()
},
set: async (value) => {
encode(value)
return store.set(null, value)
},
remove: async () => {
encode('', {maxAge: 0})
await store.remove()
},
cookies,
headers,
}
}
var sessionStore = () => {
var sid = signature.unsign(cookies.input[name] || '', secret)
|| crypto.randomBytes(20).toString('hex')
return {
get: async () => {
return await store.get(sid) || {grant: {}}
},
set: async (value) => {
encode(sid)
return store.set(sid, value)
},
remove: async () => {
encode(sid, {maxAge: 0})
await store.remove(sid)
},
cookies,
headers,
}
}
return embed ? cookieStore() : sessionStore()
}
}

8
server/node_modules/grant/lib/util.js generated vendored Normal file
View File

@@ -0,0 +1,8 @@
var compose = (...fns) => (args) =>
fns.reduce((p, f) => p.then(f), Promise.resolve(args))
var dcopy = (obj) =>
JSON.parse(JSON.stringify(obj))
module.exports = {compose, dcopy}