All

President’s Day Ponderings: The Power of Pings

[ping]

This morning, I was having a self-reflective moment, typing up some thoughts on my laptop, when my cellphone obnoxiously interjected its chipper PING into my reverie. I usually keep my phone on silent during the week, to keep it from distracting me at work, so when it’s on during the weekend that’s when I’m being social and interacting with friends. It’s logical that the sound normally triggers a brief pulse of excitement. I glance at my phone.

6:38 am. Charlotte Rousse. Last call! ALL DRESSES & SHOES $20 OR LESS! Ends tonight!

Ugh, I never shop here anymore. I tossed the Pixel back under my pillow. 5 minutes later:

6:44 am. MileagePlus Partner. Take home 1,500 miles when you dine out Who cares??

But this time, before thrusting my phone aside, I realized how I do this exact same routine with so many things in my life. Something or someone does something that bothers me a little bit, but my reaction is so minor and passes so quickly that I never bother addressing it. I don’t think it’s a terrible habit, and is something I think I’ve actually deliberately developed over time to have a more ‘chill’ persona that balances out my incredibly Type A personality, but what it means now is that I end up tolerating a lot of bullshit.

Let’s be clear. I am not a pushover by any means. If you wrong me or do something blatantly inappropriate or offensive, I’m not afraid to call you out on it. My mom jokes that I get my short temper and bluntness from my father, and the little kindness I have from her. Over time, I think I’ve grown more into my mother. Patient, forgiving, compassionate, and thoughtful–all traits I value and try to foster both in myself and other people. But, just in the last couple hours, my phone has pinged 12 times. Useless emails I never open and only irritate me. Facebook reminders that it’s people’s birthdays, which I’m sure are helpful for some but for a person like me who actively remembers her friends birthdays…. pretty useless. Instagram telling me someone posted a story for the first time in a long time.

So, why don’t I unsubscribe from these emails? Why don’t I turn off these notifications as soon as I get them? Why do I let certain people say or do things that very clearly bother me, but I just brush them off and wait for the annoyance to pass? The answer is probably both a flaw and a great skill– it’s the ability to compartmentalize and take these feelings and put them into a box and in the end I forget about it and it doesn’t really matter. Because honestly it doesn’t. People don’t usually mean to hurt me; these useless pings don’t actually hurt me; I like not dwelling on things and just moving on.

But I’m starting to realize putting things into a box requires energy, and I’ve developed a bad habit of putting everything that doesn’t need to be addressed, into a box. Work issues–yes I’ll deal with that. Fought with my best friend– of course I will deal with that too. But a white lie from a friend that I learn of from social media, or a reminder of a past encounter that I want to wipe from my memory forever, or knowing what my ex is doing… these are all things I could probably save a lot of my energy on. Because even though I put things in a box and forget them, I still have to deal with that brief moment of sadness. And why not get back those moments that could be moments of happiness instead?

Right before I wrote this post, I went in and unsubscribed from every single useless email sender. There were at least 15 on the list. And my phone has been wonderfully silent. I know I could go into my social media account settings and just disable notifications, but I’m curious to try a new exercise and just completely turn them all off. And for the week, just focus on living life in the present. I wonder how many moments of happiness I’ll get back.

Will report back.

Your Only Five Friends in the World

If you were only allowed to have five friends in the world, who would be your five?

The number 3 person on my list asked me this question the other day. And in turn I asked it to a few other people. You’d think it’d be awkward to ask this to someone who is definitely not in your top 5 or vice versa, but I think it’s a mark of a sincere friendship if you can feel comfortable enough with someone to understand and not be insecure about that. Anyway, it’s an interesting thought exercise. A nice caveat is that these are 5 friends excluding your future spouse/life partner, and your family. So no, you don’t have to worry about fulfilling your sexual needs and figuring out who to spend time with on the holidays.

My first three names came quite easily.

Number 1: My best friend. I’ve known her 8 years. We know the best and worst parts of each other, and we accept each other for everything that we are. We support and encourage each other in both personal and career growth. And when I make mistakes and want to crawl into a hole and never come back out, she doesn’t pull me out, she’ll crawl right in there with me. If I told her I murdered someone, she would respond: “I bet they deserved it.”

Number 2: My best friend at work. We have the same work ethic and drive, but also the same thirst for life / fun / adventure. The kind of person where we’ll kill ourselves to get s*** done but at the end of the day hide out in a conference room drinking mimosas to unwind.

Number 3: The person who asked me this question. I can talk to him about almost anything. And we enjoy doing anything together. And if I asked him to fly with me to Greece next month, he would probably do it. I need that kind of person in my life. The kind that is always willing to go on adventures with me. Because yolo.

At this point, I stopped being so sure. These would be my only friends for the rest of my life. The last two people would need to be able to fill whatever needs or gaps the first three couldn’t. Plus I have so many wonderful friends my life, and the idea of having to exclude them felt really awful. But that isn’t a reality I have to ever actually deal with it, so treating this like the thought exercise it is, I tried to consider what exactly it is I value in a long term friendship. And what qualities, to me, makes a person irreplaceable. It was surprisingly not a very long list, but friends are all about quality, not quantity, right?:

1. They love me for, not despite, my flaws. (And vice versa). #1 and #3 especially never make me feel bad about my flaws. They accept them and know I’m constantly working to make myself better. It’s incredibly difficult to find people who can’t help but judge you and hold your flaws against you. Even harder to find people who accept your flaws. And the hardest thing to find is not someone who blindly loves you, but rather someone who knows your faults yet appreciates that those faults are part of what makes you, you.

2. We think similarly. Not in that my friends always agree with me, or even that we have the same philosophy or attitude towards life. I don’t know how else to describe it other than that we can describe our thought process towards something to each other, and the other person would just get it. Perspective empathy, if I had to coin a phrase. I guess this sometimes results in having similar mindsets towards work, having fun, friendship, and life in general. Which is also nice ;) But not necessary.

3. Mutual respect. It’s amazing how important respect is. Respect is what drives you to answer that text and not forget to answer someone, no matter how busy you are. Respect nurtures consideration and thoughtfulness towards another person. Respect means not doing hurtful things like dating your ex-boyfriend or lying to you or talking about you behind your back. Respect means being willing to tell you like it is, because they want the best for you. Respect means trust. Because would you ever respect a person you couldn’t really trust?

4. Supportive. Sounds obvious, but I’m the kind of person who doesn’t really like to show any weakness. I don’t like needing anyone. So if I feel comfortable enough to share my woes and weaknesses with a friend such that I require their support, well… they’ve crossed a bridge that many people haven’t. And I will have crossed their bridges too.

5. Makes me feel alive. Yep. The first four seem cookie cutter; this one less so. Make me feel alive. I could say: “Challenge me and push me outside my comfort zone” — but the reason I want to be challenged and pushed is because it makes me feel alive. I’m not an adrenaline junkie, but I enjoy the thrills and highs life can provide. I’m often content to sit in my own bubble of stability, so I need a friend whose energy I can build off of (and vice versa) to create the kind of memories and excitement that you remember years later with a huge grin on your face. That quick rush of crazy should I really be doing this and your friend answers why the hell not?

Quality 5 is how I filled the last two spots. Number 4 is an old friend who I didn’t initially include because we don’t think similarly and her approach towards life is one I don’t really understand, but I think that’s how she makes me feel alive. She will do things for the sake of doing them and enjoys them in the moment, and doesn’t get caught up in the end (means vs end) the way I might. To feel alive, you have to live in the moment, and this is something spending the last 5 years with her has taught me well. And she has also been with me in some of the darkest moments of my life. That girl has seen me cry. Supportive AF.

My number 5 was almost my last ex-boyfriend, because even now, he still fulfills 1-4. But I get enough of 1-4 from the others, so my number 5 is someone I dated last year. Not really him, exactly, but everything that he is. Events and circumstance make it hard to actually be good friends, but while he somewhat fulfills #2 and #4, he fulfills #5 very well. But that in of itself isn’t why I value him. He makes me feel alive while at the same time is an interesting combination of the first four people on my list. A great combination of the qualities I admire and the flaws I embrace.

I guess my number 5 is a cop-out, since it isn’t a real person but the idea of. I think I’ll leave that spot open for someone to fill one day.

Try this thought exercise. You might be surprised at how difficult it is. And how difficult picking that last person is. (And if you really feel bad for excluding some of your friends, you can do what I did and tell yourself they’d fit perfectly into your top 10 ;))

Testing the Stingray Widget

Black Orpheus – Part 1/? Or Just In Progress.

Every single tap on the keyboard stings.

I do not consider myself a true alpinist. Thus, in between the crushing hug of 4am freezing temps and the very real possibility of sliding off a cliff whilst attempting to traverse frictionless wet slab descents in the dark, I found myself browbeaten into submission by a seemingly harmless Red Rocks climb, Black Orpheus. It was my first ever long multi-pitch route and perhaps (*cough*definitely) the wrong choice for someone who had never done either multi-pitch or trad before, but I believe my partner secretly craved the seductive beckon of the bivvy cave. This thirst for adventure is one I recognize in many of my fellow climbers, but that day as I recall a desperate rappel in the dark and terrifying wet slabs, we got much more than a healthy quenching.

2017-01-15 05.21.34(On the approach)

We went MLK weekend. Our day began at 3:45AM. Clothes, drive, harnesses, gear, and we were off.
For an hour we hiked easily towards Oak Creek Canyon, and we arrived at the mouth with an hour before the sun rose. After passing Solar Slab Gully, the trail merged into the wash where we had to scramble up large boulders. The further we went into the wash, the more difficult the scramble. I imagine the approach (and the descent) would have been much easier if it hadn’t just rained the day before.
Our early start in darkness may have caused us to miss the white boulder signaling the cairned approach, so after half an hour of failing to find a reasonable way up, we bushwhacked our way to the slabs. At this point, the entire face of Black Orpheus was blanketed in a beautiful red-orange glow.
2017-01-15 06.56.07
Halfway up, I tripped over a rock right into the side of a cactus. Luckily, I only grazed it, and we stopped for a few minutes so I could remove my pants and extract the spines. Oh those goddamn cacti. I was traumatized for the rest of that climb and paranoid that every step I took would land me knee deep in pins and needles.
When we finally reached the start of the climb, 3 hours later, it was 7:30am. We were already behind schedule. We took a quick bathroom break, pulled out the rope, and started getting ready. Andy was on the wall shortly after 8am. The first pitch was a 5.8 corner with relatively sparse gear in the first 50 feet. He reached the anchors quickly, and I followed. At this point, I was grateful for our ‘practice’ trad multipitch the previous day, when I got to first experience removing trad gear and learn the process for following.
Part 2 to come :)
Credit where credit is due. Based off climbing notes by my partner Andy Cao.

Getting Started with Building An App with React Native, Genymotion, and Watchman

Some Friday nights I like to hang out with my friends. Other Friday nights I enjoy going to the movies. This particular Friday night, I wanted to learn how to build a mobile app using react native. And I’ve heard great things.

Anyway, maybe it was the slow internet at my parents’ house in CT (Bay Area high speed internet, oh how you’ve spoiled me) or the many months it’s been since I’ve done any sort of mobile app development, but just getting to the first line of React code was a process for me. I’m putting together this tutorial specifically for those who have gone to the Facebook docs to learn how to start developing an android app with react native on a Mac, but ended up jumping around back and forth in the tutorials, and hitting random errors with watchman or Genymotion, for which googling does not always turn up any answers.

Here are the steps I followed, step by step, based off the React Native documentation here, with the errors I hit and how I fixed them. This tutorial assumes basic knowledge of node/nvm, bash, brew, and Mac OS X.

Requirements
– OS X
homebrew
– git

Basic Setup
1. Install node.js 4.0 or newer
2. brew install watchmaninstall to avoid hitting a node file watching bug
3. brew install flow to use flow

Android Setup
This is the part that took me the longest. Unfortunately (or I guess fortunately) I just bought the new Nexus, but no USB cable that can plug it into my laptop. So, I had to install the Android SDK and an emulator so I could work on my React Native for Android on my laptop.

1. Install the latest JDK if you don’t already have it
2. brew install android-sdk
3. Define the ANDROID_HOME environment variable:
export ANDROID_HOME=/usr/local/opt/android-sdk
Add the above to your ~/.bashrc or your ~/.bash_profile, keeping in mind that if you do add it to your ~/.bashrc make sure you’ve added source ~/.bashrc to your ~/.bash_profile. Once you do this, you’ll need to restart your Terminal before the environment variables will be applied. (What is all this?)
4. Start a new shell and run android. The Android SDK Manager should open.
5. Install the following:
– Android SDK Tools
– Android SDK Platform-tools
– Android SDK Build-tools
– SDK PLatform
– Intel x86 Atom_64 System Image
– Intel x86 Atom System Image
– Android Support Repository
6. Click “Install packages…” and a pop up will show up. On the left list of “Packages” click through each one and check the ‘Accept’ box on the right. Once all have been checked, click “Install.” Go grab a hot chocolate. This will take a while. While that’s installing, feel free to do the next step (initializing your project).
7. Once that is done, go back and check that all the packages have installed. When I did this, not all of them ended up installing so I had to check them again and re-install those.

Initialize Your React Project
1. Run npm install -g react-native-cli
2. In the directory where you want your project, run react-native init MyReactNativeProject

Install Genymotion
I decided to set up Genymotion instead of a stock Google emulator, but I may end up switching anyway since it’s free only for personal use.

1. Download Genymotion here. You’ll have to make an account. Remember your username and password as you’ll need it later.
2. Open Genymotion. If you don’t have VirtualBox it may ask you to install it (I already had it).
3. Click the plus sign “Add” to add a device. (You’ll have to sign in).
genymotion

 

 

 

 

 

 

 

4. Select a device and wait for it to be retrieved and deployed.
5. Finally, back in the screen that lists “Your Virtual Devices” select the device you’ve just installed, and click “Start” in the top left corner. Your device should pop up and look something like this:
Screen Shot 2015-12-20 at 4.52.53 PM

 

 

 

 

 

 

 

 

 

 

Run Your Project
This is where I hit several issues.

1. cd MyReactNativeProject
2. react-native run-android --stacktrace. The stacktrace part is optional, but helpful.
This step should open up another terminal window.

Error 1:
SDK location not found. Define location with sdk.dir in the local.properties file or with an ANDROID_HOME environment variable.
Solution: Make sure your bashrc is configured correctly with the environment variable in Android Setup Step 3, and that you source it in your bash_profile. If that still doesn’t work, another alternative is to go into the android directory, create a file called local.properties and in it add sdk.dir = {Path of your android SDK}.

Error 2:
Screen Shot 2015-12-19 at 12.35.03 AM

 

 

 

 

 

 

 

 

 

I got the above error when I tried step 2 again, and when I reloaded the JS I got a slightly different but equally useless error. However, I checked the newly opened terminal window for any errors and I got something like this:
launchctl: Couldn't stat facebook.watchman.plist: No such file or directory

Solution:
brew uninstall watchman
launchctl unload ~/Library/LaunchAgents/com.github.facebook.watchman.plist
rm ~/Library/LaunchAgents/com.github.facebook.watchman.plist
brew install --HEAD watchman
react-native run-android

Error 3:
Finally I got another error that looked like:
ERROR connect ECONNREFUSED /usr/local/Cellar/watchman/HEAD/var/run/watchman/amira-state/sock
{"code":"ECONNREFUSED","errno":"ECONNREFUSED","syscall":"connect","address":"/usr/local/Cellar/watchman/HEAD/var/run/watchman/amira-state/sock"}
Error: connect ECONNREFUSED /usr/local/Cellar/watchman/HEAD/var/run/watchman/amira-state/sock

Solution:
Add export TMPDIR=/tmp to my .bashrc file.

The above took me a few hours what with all the installation and trying to figure out all of the steps I needed to do, and a decent amount of time googling the errors I kept hitting, which were not easily findable (and sometimes I had to do things in a certain order before it’d work). If you come across this blog post and find other issues, please post them and their solutions and I’ll add it to this list!

Until then, have fun building your app!! Next up for my blog, cool tips/tricks I discover as I build in React Native!

FitRPG: The Gamification of Fitness

An RPG mobile app like no other – get fit and turn your fitness data into skills, experience points, and HP to engage in battles against your friends

Fitness trackers like Fitbit, Nike FuelBand, and Jawbone all work to solve a common problem– motivating users to get fit and stay fit. When I first started using Fitbit, I was inspired by seeing my data every single day. My dashboard was either a blunt reminder that I was not moving very much, or a beautiful screen filled with all the goals I’d accomplished that day. I felt rewarded when I received a badge or passed a fellow Fitbit friend in the rankings. But after a while, the badges were all the same, and I lost motivation to try to surpass my friends.

Screen Shot 2014-06-09 at 12.20.15 PM

Why? Because a fitness tracker is just that–it tracks your fitness, but it doesn’t add any additional features or rewards for motivation. That’s where FitRPG comes in, a mobile app that uses the data from Fitbit and turns it into a fun game that constantly inspires the user to walk more, sleep more, and work out more.

Our team (Amira Anuar, Conor Fennel, and Matt Gutierrez) worked for 2.5 weeks on this Hack Reactor group project. We created an app that allows you to sync your Fitbit and see your steps, sleep, logged workouts, and more become transformed into strength, endurance, HP, dexterity, and other attributes your character can use to battle your friends or go on quests.

   screen1 screen2

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Sleep to revitalize your HP. Log workouts to increase your strength and dexterity. Increase your steps to improve your experience and endurance.  Battle your Fitbit friends to steal their gold. See how you rank against other players in the leaderboard and increase your ranking by battling bosses and leveling up. Go on timed solo quests, which range from walking 5,000 steps to running a marathon. Win gold and experience if you succeed.

To get started, just download the app from the Google Play Store and log in with your Fitbit account. For any further questions, you can view the FAQ here or email our team at fitrpg@gmail.com. iOS version coming soon.

Take fitness to another level, literally.

Mobile Authentication in Ionic with OAuth Through External APIs: Fitbit Pt 2 (Client)

In this post I talk about how to hook up the server to the client side so a user can open your app on their phone and log in through their Fitbit account. If you haven’t read the post on setting up server for mobile OAuth, I recommend you start with that first.

Client-Side (Requirements: angular.js and ionic)

Step 1: Create the Login Service 

First, you will want to create the login service, in which you inject localStorageService, which you would need to install from here and then require in your index.html. Once you’ve done that, this is what your service should look like:

Screen Shot 2014-06-15 at 8.47.54 PM

 The url is what the server url you have that redirects a user to be logged in.  Line 9 will open an in-app browser with no toolbar or url displayed. Line 10 adds a listener called ‘loadstart’ which is called every time a new url is being loaded in the in-app browser. When this in-app browser opens, the view should look something like this:

Screen Shot 2014-06-15 at 8.53.23 PM

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Once the user logs in, he/she is redirected, as per the server. The url will change, as per the server. The rest of the code basically listens for the url that will eventually have the oauth_token that we want, as well as the user id. This particular code also listens for the JSON web token. Once you receive the token/information you want, via the URL from the server, you use localStorageService, which is basically a caching service, to store the tokens locally.

Step 2: Authenticate the User

We then want to have a controller that checks for the locally stored tokens, and if they’re there, we can direct the user to the authenticated view (line 7), and if not, we let the scope know that the user is not authenticated (line 11). All line 6 is doing is retrieving the user information from the database, using the userId to make that query.Screen Shot 2014-06-15 at 8.59.05 PM

On line 14, we have the function for logging out, which simply clears the localStorageService of all saved information, and essentially resets the ‘session.’ Line 16 basically refreshes the page, which would be unauthenticated, and line 11 would be true, and the user would be redirected to the login page, where they will be given access to something to click that will run line 21.

Step 3: Putting It All Together

Finally, we just need to hook up the views and the controllers.

Screen Shot 2014-06-15 at 9.02.49 PM

Line 4 is where we can insert our views for the app, and no user can see them unless they are authenticated. If there is no user saved to local storage, then lines 7 to 18 would show, which would be your splash screen with a button allowing the user to log in, such as our app shows below:

Screen Shot 2014-06-15 at 9.07.07 PM

 

 

 

 

 

 

 

 

 

And there you have it! Shameless plug: If you have a Fitbit and want to make fitness more fun, check out my app in the Google Play Store!

Mobile Authentication in Ionic with OAuth Through External APIs: Fitbit Pt 1 (Server)

Shameless Plug: The following steps were used in the creation of FitRPG, a fitness gamification mobile app. Download it in the Play Store now!

During a 24 hour Hackathon, I was able to fairly efficiently allow users to authenticate through Fitbit login via a web browser. I primarily used OAuth and passport. However, when I decided to create an Ionic mobile app that allowed users to authenticate client-side through Fitbit/Jawbone (and really any external API that does authentication through OAuth 1.0/2.0), I ran through several issues and could find very little online support. In the end, it’s really not all that complicated–the key is we have to use our server-side to authenticate users, and we need an in app browser client-side.  It’s important to note that every API is a little bit different, and while I cover only Fitbit authentication in this post, the same general concepts can be used for other APIs as well. This post covers the setting up of the back-end, my next post covers the setting up of the friend end. You must do both for this to work as they depend on each other. Make sure you get your consumer key and secret from Fitbit upon registering your app.

Server-Side (Requirements: node.js and express 4.0)

Step 1: Set up Passport  First, we set up Passport, authentication middleware for node. Passport authenticates requests through ‘strategies’ you provide. In other words, we tell Passport what requests to authenticate, and it provides hooks for controlling what happens when authentication succeeds or fails. To do this, we jus require and then initialize it. Screen Shot 2014-06-07 at 12.55.24 PM

 

Step 2: Set Up Your Strategy with Passport Strategies are what Passport uses to authenticate requests. You can use them to verify a username/password combination, for instance, or to delegate authentication to OAuth, which is what we are doing in this situation. Before passport can ‘use’ a strategy, we have to configure it. Usually you do not have to create the strategy yourself–Passport has a pretty comprehensive set of over 140 authentication strategies that cover social networking, API services, and so on. I used the fitbit-passport strategy. On web, the fitbit-passport works fine as is, but on mobile, there is a tweak we want to make so that the login page shows up as mobile-friendly. I ended up having to make a copy of the node module and storing it in the body of my app files. Change the line that assigns options.userAuthorizationURL to:

Screen Shot 2014-06-09 at 2.28.32 PM

 

Step 3: Configure Your Strategy with Passport To configure the strategy, you must create a new strategy and pass in a) an object with your Fitbit consumerKey, consumerSecret, and callbackURL (more on that later), and b) a callback function that occurs once authentication is successful–this function will receive the token, tokenSecret, and profile from passport. Finally, you tell passport that it needs to ‘use’ that strategy.

Screen Shot 2014-06-07 at 2.07.11 PM

Step 4: Create Your Routes I used Express 4.2, and express.Router() to handle my routes. When my site goes to ‘/’ it uses the FitbitRouter. I could have also done “app.use(‘/fitbit’, FitbitRouter)” and that would have handled all of the routes on my site that start with ‘/fitbit’. In this particular case, my authentication page is just at mywebsite.com/auth, so that is where I will direct my mobile app to when I want to authenticate the user (more on that later). Step 5 covers the logic behind lines 4 and 5, but if you just want the code, skip to step 6 for the function in line 6. Screen Shot 2014-06-07 at 2.14.43 PM

Step 5.1: Get the Temporary Access Token The only endpoint we need to write is for that last route, as the first two just use the passport middleware. However, it is important and useful to understand what is going on. First, when we have a route that uses ‘/auth’,  which is the route we direct users to when we want them to authenticate via Fitbit. On our client side, we will be opening an in-app browser that goes to this url (see Pt 2). When we go to this page, we use passport.authenticate(‘fitbit’) as middleware, with ‘fitbit’ referring to the strategy we’ve declared earlier. Passport does work in the background to do the first step of the authentication process. What’s basically happening is passport then sends a post request to Fitbit (taken directly from Fitbit API documentation):

Screen Shot 2014-06-09 at 2.13.08 PM

Fitbit then sends back a response with a temporary OAuth token, which Passport receives and then uses to recreate a redirect url with, which looks like this: https://www.fitbit.com/oauth/authorize?display=touch&oauth_token=47617140d6906e7db65ac71df26290c0. The temporary oauth_token expires upon usage or within a few minutes. So to summarize, the middleware works to create that token and redirects users to a Fitbit login page where they can fill in their username and password.

 

Step 5.2: Get the OAuth Verifier Once the user is successfully signed in, Fitbit will redirect the user to the callback that you have provided, which in this example is the route to ‘authcallback’ (see step 3 above). The callback URL also includes Fitbit’s response, with the temporary OAuth token and a token verifier, which looks like this: http://example.fitbit.com/app/completeAuthorization?oauth_token=c5a8b2ff2a20524381083b1fe172fdc1&oauth_verifier=car3fbtjvralpv4kvba65arls2 With this verifier, passport (which is again included as middleware for that callback route) does another POST request to Fitbit, which looks like this. Screen Shot 2014-06-09 at 7.33.01 PM

Step 6: Save the OAuth token and OAuth token Secret Fitbit’s request comes back with the OAuth token and OAuth token secret, both of which you will need to access the user’s data in the future. Passport sends the token and tokensecret to the callback function shown in step 3. Passport also does additional work of getting the user’s profile for you.  From this point, it’s up to you what you do with that information, but I recommend saving the token and tokensecret, and then using fitbit-node‘s requestResource function to retrieve data for that user. Once you have the token/tokenSecert, it’s pretty straightforward from there.

Step 7: Respond to the Client At this point, our client is waiting for a response from our server, which is the responsibility of our function ‘getOuthToken.’ All that function needs to do is redirect to a url that will basically notify the client that the process has completed, and the in-app browser can be closed. In my example below, we use JSON web tokens, which are tokens generated to ensure the security of our app (the user must make resource calls with this JSON web token). Your app can capture the ‘oauth_token’ in the request, and send that back to the client to save, or your app can merely redirect to any link, as long as you check for that in the client side. My app sends the JSON web token back in the url for the client to capture. Screen Shot 2014-06-09 at 7.59.56 PM
That’s it! 
You’re done (sorta – you need to implement the client side on ionic – see next blog). Once you complete these steps, your user has signed in via Fitbit! As I said before, if you want to make resource requests on behalf of the user, I’d recommend using fitbit-node. Good luck, and please comment if you have any questions.

Week 5 at Hack Reactor

Reflecting on my time here so far, I feel like I’ve gone through some pretty distinct phases of

– yes! I totally know what I’m doing

– severe impostor syndrome… how the hell did I end up here? I have no idea what I’m doing.

– there is way too much to learn and I am never going to learn it all as thoroughly as I want to

– pairing is hard

– I love pairing

– I love Marcus, Phillip, and Fred, so so much

– why do Marcus, Phillip, and Fred cold-call so much? it’s torture!

– javascript is weird…

But at the end of the day, I go home feeling pretty satisfied with everything I’ve done that day, and every morning I head into Hack Reactor excited to continue thinking through and solving problems through code.

Also, an aside, I have finally moved up to SF! Shorter commute ftw.

Considering your OPTIONS: Cross-Domain Ajax Requests and CORS

A couple days ago, my partner and I built the server side for our (previously created) client side of Chatterbox–a group messaging web app. The client sends specific requests to the server, which then sends back the requested chat messages. Something we spent a reasonable amount of time debugging was the “OPTIONS” requests that our client side kept sending…and our server was apparently ignoring. I knew “GET,” knew “POST,” but what was this incredibly annoying “OPTIONS” request that prevented my much desired requests from going through? Turns out, this was a result of our server making cross-domain ajax requests to our client. Our server was not located at the same domain as our client, and they thus had different origins, so to speak.

In this particular case,  we could have fixed this problem by making sure the client and server were located on the same origin. However, we decided to tackle the ‘OPTIONS’ request, because that is something that will be necessary any time you want to make Ajax requests to domains other than your own. For example, let’s say you work at Github (if only, right??), and you want to allow certain other websites to allow their users to log-in to the site with their Github account. These sites would have widgets that communicate with Github. You now have two origins in play. But, for security purposes, the browser has introduced restrictions on how you may communicate with domains other than the one you are in (the one in your url bar).

I won’t go into the details of the possible security implications of not having these restrictions, but imagine a lot of malicious code getting injected in lots of places and basically just breaking the internet. A major drawback of these restrictions is that it makes it much more difficult for our website to communicate with other websites. Over the years, various techniques have been used as workarounds, one of which is called CORS – Cross Origin Resource Sharing.

 

601px-Handshake1.svgIn layman’s terms, CORS is like a handshake between your domain and the server you want to interact with. You reach your hand out, and the server agrees (or disagrees) to shake it. More specifically, when the browser notices you are making an Ajax request to a domain other than your own, it will suspend your Ajax request and call out to the server with an ‘OPTIONS’ method that provides information about the origin, and basically asks the server: “What is your allow policy?” The server should then ideally be set up to respond to ‘OPTIONS’ requests with a response that includes headers that indicate whether it will serve resources to the origin, as well as what specific actions your domain is allowed to perform on the server (i.e. get, post, etc.).  If the server responds with a heading of “Access-control-allow-origin: *”, that means all origins are allowed, and hurray–your Ajax request can go through. The server can be even more specific, and may very well choose to respond and say that it will only allow certain methods (GET ok, but not DELETE), or it may respond that it will not serve any sort of resources to the origin.  (Check out how the Github API supports CORS here!) This exchange, much like a handshake, is what makes CORS secure.

CORS is supported by all major browsers. So now are you considering your options? Of CORS you are!