Skip to content

Instantly share code, notes, and snippets.

@siejkowski
Created December 1, 2020 10:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save siejkowski/e0774dd244fcc61e73558fedd466b79b to your computer and use it in GitHub Desktop.
Save siejkowski/e0774dd244fcc61e73558fedd466b79b to your computer and use it in GitHub Desktop.
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
function makeErrorResponse(message) {
return new Response(message, {
status: 404,
statusText: 'not found',
headers: {
'content-type': 'text/plain',
},
})
}
async function swap(request) {
const requestData = await request.formData()
const body = {}
for (const entry of requestData.entries()) {
body[entry[0]] = entry[1]
}
const requestCode = body["code"]
if (requestCode == undefined) {
return makeErrorResponse("no required code parameter")
}
const grantData = 'grant_type=authorization_code'
const redirectData = 'redirect_uri=' + SPOTIFY_REDIRECT_URI
const codeData = 'code=' + requestCode
const clientIdData = 'client_id=' + SPOTIFY_CLIENT_ID
const clientSecretData = 'client_secret=' + SPOTIFY_CLIENT_SECRET
const spotifyRequestBody = grantData + '&'
+ redirectData + '&'
+ codeData + '&'
+ clientIdData + '&' +
clientSecretData
const init = {
body: spotifyRequestBody,
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
}
}
const url = 'https://accounts.spotify.com/api/token'
const spotifyResponse = await fetch(url, init)
if (spotifyResponse.status != 200) {
const errorResponse = await spotifyResponse.text();
return makeErrorResponse("Spotify returned error: " + errorResponse)
}
const spotifyJSON = await spotifyResponse.json()
refreshToken = spotifyJSON["refresh_token"]
const encryptedRefreshToken = await encrypt(refreshToken)
spotifyJSON["refresh_token"] = encryptedRefreshToken
const responseBody = JSON.stringify(spotifyJSON)
return new Response(responseBody)
}
async function refresh(request) {
const requestData = await request.formData()
const body = {}
for (const entry of requestData.entries()) {
body[entry[0]] = entry[1]
}
const encryptedRefreshToken = body["refresh_token"]
if (encryptedRefreshToken == undefined) {
return makeErrorResponse("no required code parameter")
}
const encryptedRefreshTokenFixed = encryptedRefreshToken.replaceAll(" ", "+")
const refreshToken = await decrypt(encryptedRefreshTokenFixed)
const grantData = 'grant_type=refresh_token'
const refreshTokenData = 'refresh_token=' + refreshToken
const spotifyRequestBody = grantData + '&' + refreshTokenData
const authorizationHeader = SPOTIFY_CLIENT_ID + ":" + SPOTIFY_CLIENT_SECRET
const base64Header = btoa(authorizationHeader)
const init = {
body: spotifyRequestBody,
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"Authorization": "Basic " + base64Header
}
}
const url = 'https://accounts.spotify.com/api/token'
const spotifyResponse = await fetch(url, init)
if (spotifyResponse.status != 200) {
const errorResponse = await spotifyResponse.text();
return makeErrorResponse("Spotify returned error: " + errorResponse)
}
const spotifyJSON = await spotifyResponse.json()
const responseBody = JSON.stringify(spotifyJSON)
return new Response(responseBody)
}
async function encrypt(decryptedMessage) {
// TODO: put your encryption here. Cloudflare Workers support WebCrypto API
return encryptedBase64
}
async function decrypt(encryptedBase64) {
// TODO: put your decryption here. Cloudflare Workers support WebCrypto API
return decryptedMessage
}
/**
* Respond to the request
* @param {Request} request
*/
async function handleRequest(request) {
const url = new URL(request.url)
var path = url.pathname
switch (path) {
case "/swap":
case "swap":
if (request.method != "POST") {
return makeErrorResponse("this endpoint only takes POST!")
}
return await swap(request)
case "/refresh":
case "refresh":
if (request.method != "POST") {
return makeErrorResponse("this endpoint only takes POST!")
}
return await refresh(request)
default:
return makeErrorResponse("endpoint not found")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment