You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
134 lines
5.1 KiB
134 lines
5.1 KiB
import Knex from "knex"; |
|
import { IntegrationImpl } from "../../client/src/api/api"; |
|
|
|
const { createProxyMiddleware } = require('http-proxy-middleware'); |
|
let axios = require('axios') |
|
let qs = require('querystring') |
|
|
|
async function getSpotifyCCAuthToken(clientId: string, clientSecret: string) { |
|
console.log("Details: ", clientId, clientSecret); |
|
|
|
let buf = Buffer.from(clientId + ':' + clientSecret) |
|
let encoded = buf.toString('base64'); |
|
|
|
let response = await axios.post( |
|
'https://accounts.spotify.com/api/token', |
|
qs.stringify({ 'grant_type': 'client_credentials' }), |
|
{ |
|
'headers': { |
|
'Authorization': 'Basic ' + encoded, |
|
'Content-Type': 'application/x-www-form-urlencoded' |
|
} |
|
} |
|
); |
|
|
|
if (response.status != 200) { |
|
throw new Error("Unable to get a Spotify auth token.") |
|
} |
|
|
|
return (await response).data.access_token; |
|
} |
|
|
|
export function createIntegrations(knex: Knex, apiBaseUrl: string) { |
|
// This will enable the app to redirect requests like: |
|
// /integrations/5/v1/search?q=query |
|
// To the external API represented by integration 5, e.g. for spotify: |
|
// https://api.spotify.com/v1/search?q=query |
|
// Requests need to already have a .user.id set. |
|
|
|
let proxySpotifyCC = createProxyMiddleware({ |
|
target: 'https://api.spotify.com/', |
|
changeOrigin: true, |
|
logLevel: 'debug', |
|
pathRewrite: (path: string, req: any) => { |
|
// Remove e.g. "/api/integrations/5" |
|
let replaced = path.replace(new RegExp(`${apiBaseUrl}/integrations/[0-9]+/`), ''); |
|
console.log("Rewrite URL:", path, replaced); |
|
return replaced; |
|
}, |
|
onProxyReq: (proxyReq: any, req: any, res: any) => { |
|
console.log('--> ', req.method, req.path, '->', proxyReq.path); |
|
} |
|
}); |
|
|
|
let proxyYoutubeMusic = createProxyMiddleware({ |
|
target: 'https://music.youtube.com/', |
|
changeOrigin: true, |
|
logLevel: 'debug', |
|
pathRewrite: (path: string, req: any) => { |
|
// Remove e.g. "/api/integrations/5" |
|
let replaced = path.replace(new RegExp(`${apiBaseUrl}/integrations/[0-9]+/`), ''); |
|
console.log("Rewrite URL:", path, replaced); |
|
return replaced; |
|
}, |
|
onProxyReq: (proxyReq: any, req: any, res: any) => { |
|
console.log('--> ', req.method, req.path, '->', proxyReq.path); |
|
} |
|
}) |
|
|
|
// In the first layer, retrieve integration details and save details |
|
// in the request. |
|
return async (req: any, res: any, next: any) => { |
|
// Determine the integration to use. |
|
req._integrationId = parseInt(req.url.match(/^\/([0-9]+)/)[1]); |
|
console.log("URL:", req.url, 'match:', req._integrationId) |
|
if (!req._integrationId) { |
|
res.status(400).send({ reason: "An integration ID should be provided in the URL." }); |
|
return; |
|
} |
|
req._integration = (await knex.select(['id', 'name', 'type', 'details', 'secretDetails']) |
|
.from('integrations') |
|
.where({ 'user': req.user.id, 'id': req._integrationId }))[0]; |
|
if (!req._integration) { |
|
res.status(404).send(); |
|
return; |
|
} |
|
|
|
req._integration.details = JSON.parse(req._integration.details); |
|
req._integration.secretDetails = JSON.parse(req._integration.secretDetails); |
|
|
|
switch (req._integration.type) { |
|
case IntegrationImpl.SpotifyClientCredentials: { |
|
console.log("Integration: ", req._integration) |
|
// FIXME: persist the token |
|
req._access_token = await getSpotifyCCAuthToken( |
|
req._integration.details.clientId, |
|
req._integration.secretDetails.clientSecret, |
|
) |
|
if (!req._access_token) { |
|
res.status(500).send({ reason: "Unable to get Spotify auth token." }) |
|
} |
|
req.headers["Authorization"] = "Bearer " + req._access_token; |
|
return proxySpotifyCC(req, res, next); |
|
} |
|
case IntegrationImpl.YoutubeWebScraper: { |
|
console.log("Integration: ", req._integration) |
|
return proxyYoutubeMusic(req, res, next); |
|
} |
|
default: { |
|
res.status(500).send({ reason: "Unsupported integration type " + req._integration.type }) |
|
} |
|
} |
|
}; |
|
|
|
|
|
|
|
// // First add a layer which creates a token and saves it in the request. |
|
// app.use((req: any, res: any, next: any) => { |
|
// updateToken('c3e5e605e7814cdf94cd86eeba6f4c4f', '5d870c84a3c34aa3a4cf803aa95cb96a') |
|
// .then(() => { |
|
// req._access_token = authToken; |
|
// next(); |
|
// }) |
|
// }) |
|
// app.use( |
|
// '/spotifycc', |
|
// createProxyMiddleware({ |
|
// target: 'https://api.spotify.com/', |
|
// changeOrigin: true, |
|
// onProxyReq: onProxyReq, |
|
// logLevel: 'debug', |
|
// pathRewrite: { '^/spotifycc': '' }, |
|
// }) |
|
// ) |
|
} |