diff --git a/api/cloudflare.js b/api/cloudflare.js new file mode 100644 index 0000000..e96860b --- /dev/null +++ b/api/cloudflare.js @@ -0,0 +1,49 @@ +addEventListener('fetch', event => { + event.respondWith(fetchAndApply(event.request)) + }) + + const mailGetKey = require("./src/cloudflare-api/mailGetKey") + const mailGetHtml = require("./src/cloudflare-api/mailGetHtml") + const mailList = require("./src/cloudflare-api/mailList") + + async function fetchAndApply(request) { + let url = new URL(request.url) + if (request.method === "OPTIONS") { + return handleOptions(request) + } else if(url.pathname === "/api/v1/mail/list"){ + return mailList(url) + } else if(url.pathname === "/api/v1/mail/getKey") { + return mailGetKey(url) + } else if (url.pathname === "/api/v1/mail/getHtml") { + return mailGetHtml(url) + } + + return new Response('Invalid endpoint - ' + url.pathname, + { status: 400, statusText: 'INVALID_ENDPOINT' }); + } + + let config = require("./config/mailgunConfig") + + const corsHeaders = { + "Access-Control-Allow-Origin": config.corsOrigin, + "Access-Control-Allow-Methods": "GET, POST, OPTIONS", + "Access-Control-Allow-Headers": "Content-Type", + } + + function handleOptions(request) { + if (request.headers.get("Origin") !== null && + request.headers.get("Access-Control-Request-Method") !== null && + request.headers.get("Access-Control-Request-Headers") !== null) { + // Handle CORS pre-flight request. + return new Response(null, { + headers: corsHeaders + }) + } else { + // Handle standard OPTIONS request. + return new Response(null, { + headers: { + "Allow": "GET, POST, OPTIONS", + } + }) + } + } \ No newline at end of file diff --git a/api/package.json b/api/package.json index f58b672..4fb8f1b 100644 --- a/api/package.json +++ b/api/package.json @@ -14,14 +14,16 @@ "devDependencies": { "delay": "^4.0.0", "mailgun-js": "^0.20.0", + "md5": "^2.2.1", "mocha": "^5.2.0", "shortid": "^2.2.13", - "md5": "^2.2.1", - "uuid": "^3.3.2" + "uuid": "^3.3.2", + "webpack-cli": "^3.3.0" }, "scripts": { "test": "mocha", - "start": "node app.js" + "start": "node app.js", + "build-cloudflare": "webpack cloudflare.js" }, "author": "", "license": "MIT" diff --git a/api/src/cloudflare/mailGetHtml.sample.js b/api/src/cloudflare-api/mailGetHtml.js similarity index 77% rename from api/src/cloudflare/mailGetHtml.sample.js rename to api/src/cloudflare-api/mailGetHtml.js index bf05fca..1ef8f50 100644 --- a/api/src/cloudflare/mailGetHtml.sample.js +++ b/api/src/cloudflare-api/mailGetHtml.js @@ -1,27 +1,25 @@ -addEventListener('fetch', event => { - event.respondWith(fetchAndApply(event.request)) -}) - /** * Making a curl request that looks like * curl -X POST --data 'key=world' example.com * or * curl -X POST --form 'key=world' example.com */ -async function fetchAndApply(request) { - const myURL = new URL(request.url); - let mailKey = myURL.searchParams.get('mailKey') + +let config = require("../../config/mailgunConfig") + +module.exports = async function(url) { + let mailKey = url.searchParams.get('mailKey') if (mailKey == null || mailKey === ""){ return new Response('Missing parameter - `mailKey`', { status: 400, statusText: 'No `mailKey` param found' }); } // Setup the authentication option object - let authenticationKey = this.btoa("api:${MAILGUN_API_KEY}"); + let authenticationKey = this.btoa("api:" + config.apiKey); let _authOption = { headers: { - "Authorization" : "BASIC "+authenticationKey + "Authorization" : "BASIC " + authenticationKey } }; @@ -30,7 +28,7 @@ async function fetchAndApply(request) { // slice the mailgunApi to include the region let apiUrl = "https://api.mailgun.net/v3" apiUrl = apiUrl.replace("://", "://"+prefix+".") - let urlWithParams = apiUrl+"/domains/${MAILGUN_EMAIL_DOMAIN}/messages/"+key; + let urlWithParams = apiUrl+"/domains/" + config.emailDomain + "/messages/"+key; const response = await fetchGet(urlWithParams, _authOption); let body = response["body-html"] || response["body-plain"] @@ -48,12 +46,16 @@ async function fetchAndApply(request) { let responseInit = { headers: { - "Content-Type": "application/json" + "Content-Type": "text/html" } } return new Response(body, responseInit) } catch (err) { - return new Response(err) + return new Response("{error: '"+err+"'}", + { status: 400, statusText: 'INVALID_PARAMETER', headers: { + "Content-Type": "application/json" + } + }); } } diff --git a/api/src/cloudflare/mailGetKey.sample.js b/api/src/cloudflare-api/mailGetKey.js similarity index 68% rename from api/src/cloudflare/mailGetKey.sample.js rename to api/src/cloudflare-api/mailGetKey.js index 62c7747..746ab48 100644 --- a/api/src/cloudflare/mailGetKey.sample.js +++ b/api/src/cloudflare-api/mailGetKey.js @@ -1,6 +1,3 @@ -addEventListener('fetch', event => { - event.respondWith(fetchAndApply(event.request)) -}) /** * Making a curl request that looks like @@ -8,31 +5,33 @@ addEventListener('fetch', event => { * or * curl -X POST --form 'key=world' example.com */ -async function fetchAndApply(request) { - const myURL = new URL(request.url); - let mailKey = myURL.searchParams.get('mailKey') +let config = require("../../config/mailgunConfig") + +module.exports = async function(url) { + let mailKey = url.searchParams.get('mailKey') if (mailKey == null || mailKey === ""){ return new Response('Missing parameter - `mailKey`', - { status: 400, statusText: 'No `mailKey` param found' }); + { status: 400, statusText: 'INVALID_PARAMETER' }); } // Setup the authentication option object - let authenticationKey = this.btoa("api:${MAILGUN_API_KEY}"); + let authenticationKey = this.btoa("api:" + config.apiKey); let _authOption = { headers: { - "Authorization" : "BASIC "+authenticationKey + "Authorization" : "BASIC " + authenticationKey } }; try { - let [prefix, key, ...remainder] = mailKey.split("-") + let [prefix, key, ...remainder] = mailKey.split("-") + // slice the mailgunApi to include the region let apiUrl = "https://api.mailgun.net/v3" apiUrl = apiUrl.replace("://", "://"+prefix+".") - let urlWithParams = apiUrl+"/domains/${MAILGUN_EMAIL_DOMAIN}/messages/"+key; - const response = await fetchGet(urlWithParams, _authOption); - + let urlWithParams = apiUrl+"/domains/" + config.emailDomain + "/messages/"+key; + const response = await fetchGet(urlWithParams, _authOption); + let emailDetails = {} // Format and extract the name of the user @@ -57,7 +56,11 @@ async function fetchAndApply(request) { } return new Response(JSON.stringify(emailDetails), responseInit) } catch (err) { - return new Response(err) + return new Response("{error: '"+err+"'}", + { status: 400, statusText: 'INVALID_PARAMETER', headers: { + "Content-Type": "application/json" + } + }); } } @@ -67,7 +70,7 @@ async function fetchAndApply(request) { * @param {String} urlWithParams * @param {Object} options */ -var fetchGet = function(urlWithParams, options){ +let fetchGet = function(urlWithParams, options){ return new Promise(function(resolve, reject){ fetch(urlWithParams, options).then(response => { resolve(response.json()) diff --git a/api/src/cloudflare/mailList.sample.js b/api/src/cloudflare-api/mailList.js similarity index 63% rename from api/src/cloudflare/mailList.sample.js rename to api/src/cloudflare-api/mailList.js index 7efb63e..5721898 100644 --- a/api/src/cloudflare/mailList.sample.js +++ b/api/src/cloudflare-api/mailList.js @@ -1,17 +1,14 @@ -addEventListener('fetch', event => { - event.respondWith(fetchAndApply(event.request)) -}) - /** * Making a curl request that looks like * curl -X POST --data 'key=world' example.com * or * curl -X POST --form 'key=world' example.com */ -async function fetchAndApply(request) { - const myURL = new URL(request.url); - let recipient = myURL.searchParams.get('recipient') +let config = require("../../config/mailgunConfig") +module.exports = async function(url) { + let recipient = url.searchParams.get('recipient') + console.log(JSON.stringify(config)) if (recipient == null){ return new Response('Missing parameter - `recipient`', { status: 400, statusText: 'No `recipient` param found' }); @@ -23,16 +20,16 @@ async function fetchAndApply(request) { } // Setup the authentication option object - let authenticationKey = this.btoa("api:${MAILGUN_API_KEY}"); + let authenticationKey = this.btoa("api:" + config.apiKey); let _authOption = { headers: { - "Authorization" : "BASIC "+authenticationKey + "Authorization" : "BASIC " + authenticationKey } }; try { - const postData = await fetchGet("https://api.mailgun.net/v3/${MAILGUN_EMAIL_DOMAIN}/events?recipient="+recipient+"@${MAILGUN_EMAIL_DOMAIN}", _authOption); + const postData = await fetchGet("https://api.mailgun.net/v3/" + config.emailDomain + "/events?recipient="+recipient+"@"+config.emailDomain, _authOption); let responseInit = { headers: { "Content-Type": "application/json" @@ -40,7 +37,11 @@ async function fetchAndApply(request) { } return new Response(JSON.stringify(postData.items), responseInit) } catch (err) { - return new Response(err) + return new Response("{error: '"+err+"'}", + { status: 400, statusText: 'INVALID_PARAMETER', headers: { + "Content-Type": "application/json" + } + }); } } diff --git a/config.sh b/config.sh index bc3bdc1..5a768e1 100755 --- a/config.sh +++ b/config.sh @@ -71,9 +71,4 @@ export WEBSITE_DOMAIN="$WEBSITE_DOMAIN" # echo ">> Applying config settings" cat "$projectDir/api/config/mailgunConfig.sample.js" | envsubst > "$projectDir/api/config/mailgunConfig.js" -cat "$projectDir/ui/config/apiconfig.sample.js" | envsubst > "$projectDir/ui/config/apiconfig.js" - -echo ">> Applying to cloudflare scripts" -cat "$projectDir/api/src/cloudflare/mailList.sample.js" | envsubst > "$projectDir/api/src/cloudflare/mailList.js" -cat "$projectDir/api/src/cloudflare/mailGetKey.sample.js" | envsubst > "$projectDir/api/src/cloudflare/mailGetKey.js" -cat "$projectDir/api/src/cloudflare/mailGetHtml.sample.js" | envsubst > "$projectDir/api/src/cloudflare/mailGetHtml.js" \ No newline at end of file +cat "$projectDir/ui/config/apiconfig.sample.js" | envsubst > "$projectDir/ui/config/apiconfig.js" \ No newline at end of file