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

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': '' },
// })
// )
}