Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API Call for Promos #157

Closed
wants to merge 5 commits into from
Closed

API Call for Promos #157

wants to merge 5 commits into from

Conversation

arpavlic03
Copy link
Collaborator

Backend for the Promo Form to post into AirTable - 10TVPromos.

Copy link
Owner

@maharris1011 maharris1011 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’d like to understand how we’re protecting the airtable key while enabling its use on the client.

@@ -59,8 +59,14 @@ <h4><br/>Offer valid until May 1st, 2020<br />To submit your business, fill out
</div>


<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is not necessary. We load it in the footer.

submitButton.disabled = true;
e.preventDefault();
var xhr = new XMLHttpRequest();
var myAPIKey = process.env.AIRTABLE_KEY;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is the environment variable set? This code will execute on the client who likely doesn’t know our Airtable key.

@arpavlic03
Copy link
Collaborator Author

Hi, once I get back online, I will change the code to use site.env.API_KEY as a hidden element in the template...which is already configured in the jekyll configuration. That way the client can obtain the api key to use to post to the airtable

@maharris1011
Copy link
Owner

i'm not sure about that either. That'll work, but the challenge is that it'll generate directly into the site code. The reason it is OK now is that the API key never shows up in the HTML/JS that goes to the client. It's only used at build time by a plugin. That won't work in this case, b/c you need to write to the Airtable directly and to do that the javascript has to have the key. The user could always "View Source" in the browser and see the key.

I think opening up an API on Amazon Lambda or Google Functions or Firebase is the right way to go in this case. With the API we could sanitize the input, do some business logic (like sending email), and protect the API key.

I'm super happy to work on this with someone if they want to. Like I mentioned, @CoreySchnedl did a killer job with some research into Firebase functions as APIs the other day.

@maharris1011 maharris1011 linked an issue Apr 5, 2020 that may be closed by this pull request
@CoreySchnedl
Copy link
Collaborator

CoreySchnedl commented Apr 5, 2020

@maharris1011 @arpavlic03 do we want to set up a quick call or slack thread to discuss what the best solution for this is? I am available anytime this evening. Unfortunately, there's no real way to do this 100% securely from what I've seen. Either A, we expose the api key client side and bad users can just make the same api calls with the api key, or b we move the logic to some back end, but that back end will be just as vulnerable as option A. Moving to lambda would only move the vulnerability to someone trying to take advantage of the public aws api gateway endpoint, and would only complicate things even if our api key would technically remain secret.. IMHO, although we probably don't want people having to do manual tasks, the best way to get around this problem is to change that form into an email template that goes to a new email that we don't care if malicious users try to spam it. Or, if that doesn't seem best, we could just add a google recaptcha to at least protect from completely malicious attacks. https://developers.google.com/recaptcha.

@arpavlic03
Copy link
Collaborator Author

Hello, unfortunately tonight is not the best night for me for a discussion. Anytime tomorrow will be better day for me to talk about this in detail

@maharris1011
Copy link
Owner

@arpavlic03 - i opened up an api this weekend at https://wduc7ys73l.execute-api.us-east-1.amazonaws.com/dev/promotions/create that takes form input & adds it to the Promotions view of the Airtable base, using the same key that @jranta used in his PRs.

if you modify your form to use action="https://wduc7ys73l.execute-api.us-east-1.amazonaws.com/dev/promotions/create" method="POST" and change the "name" attributes on the form items to "Business", "Promo", and "Website", respectively, you don't need any javascript or api keys or anything on the page for posting to Airtable.

It solves the problems with api keys we talked about and reduces the need for code in your PR.

Attached is a Postman file that you can import to work with the API directly (change to .json extension first)
CantStopColumbus.postman_collection.txt

reject("Failure");
}; });

async function myFunction() {
Copy link
Collaborator

@seanlawrenz seanlawrenz Apr 6, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want to use async we'll need to add babel to the project.

And if we're doing that, we should use fetch.

Copy link
Collaborator

@seanlawrenz seanlawrenz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haven't tried this locally but we'll need to add babel if we're going to use async await pattern.

I'm in favor of doing that pattern but jquery will handle it for us if we don't.

e.preventDefault();
console.log("COMMENCING CHECK");
myFunction()
.catch(stuff => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mismatching .catch and async.

On async and await functions, you want to use a pattern of try ... catch.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Sean! I will be talking to Mark tomorrow but there might be a possibility that we don't need the async/await at all if we call a lambda-oriented api that can handle the post for us and hopefully check for duplicate records.

In any other case, I would definitely agree with you. It worked locally on my machine with the catch, .then, asyncs, awaits and Promises with good ol' jquery but instilling try/catch in all of my functionality will be much more helpful.

@arpavlic03
Copy link
Collaborator Author

@maharris1011, just wanted to let you know before our call that the api works! Thank you so much for all of your hard work with this.

@arpavlic03
Copy link
Collaborator Author

I am closing this PR until we get the green light from TV10 regarding the Can't Stop Columbus partnership

@arpavlic03 arpavlic03 closed this Apr 7, 2020
@maharris1011 maharris1011 deleted the promoAirTable branch September 14, 2020 15:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10tv partnership
5 participants