All Projects → pathikrit → vocowl

pathikrit / vocowl

Licence: other
A smart flashcard app

Programming Languages

coffeescript
4710 projects

Labels

Vocowl

vocowl is my attempt to prototype a no-backend server-less app that securely authenticates users and accepts payments.

Yes, you can host the index.html on your machine and even though you don't have access to any of my sensitive data (like how many users I have or my private Stripe API key), the app would still work (it will authenticate users and sends payments to me).

You can test this by going to http://vocowl.com which is hosted on GitHub pages and using a test credit card (or a real one if you want to thank me :-))

This technique will let you host sophisticated client-side only apps on static file servers like DropBox or GitHub pages or out of S3. It also makes it possible for users to simply save and use the app locally from their own devices.

Vocowl elavator-pitch:

Vocowl is a collaborative community edited flashcard sharing app where you can upload, share, browse, categorize, rate and edit flashcards and design your custom lessons in a wide variety of topics.

We think plain old passive flashcards are boring so we reinvented them to be interactive and we came up with smart models to keep track of your level of learning and use intelligent algorithms to decide what flashcard to show you next based on your recent performance in your topic of interest.

We are still in the early stages and therefore to get started, we parsed the most frequent 5000 words that have showed up in the past 10 years in the GRE, TOEFL and the SAT exams and created a demo app at http://vocowl.com to show how fast, fun and easy it is to use vocowl. We plan to keep vocowl completely open-source and server-less i.e. you can save the webpage and easily run your own copy of the app anytime anywhere.

Technical details:

tl;dr: To create server-less apps, store data in Firebase and store complex logic and private keys in Webshell.io. To get started, you can look at the code in app.coffee file.

Detailed explanation of a complex operation e.g. charging a credit card using Stripe:

  • I use Persona for server-less client-side user-authentication

  • I store the user credentials in Firebase - Firebase lets you store data in a database and access it directly using their client-side JavaScript SDK

  • I use Stripe to accept credit cards from the user and create a client-side charge token using their checkout library

  • I still need a server to submit my charge request to Stripe using my private Stripe keys which I do not want to expose in client-side JavaScript. This is where Webshell.io solves the problem of not having a server. Webshell.io lets you host arbitrary javascripts on their servers and you can execute these scripts from client side using their WebShell SDK. You won't know what was executed in the client side but just get the final result. This way you can safely store your private Stripe API key in Webshell.io and simply let it make the actual charge credit-card request.

  • WebShell has convenient methods to make GET and POST requests from the hosted JavaScripts. The stored JavaScript in Webshell.io is very simple and it looks like this:

var stripe_apiKey = 'stripe private key';
var firebase_authKey = 'firebase private key';
var amount = 1000;  //$10.00 in cents

module.exports = {
  charge: function(args) {
    var receipt = post({
      url: 'https://api.stripe.com/v1/charges',
      headers: {
        Authorization: 'Bearer ' + stripe_apiKey
      },
      params: {
        amount: amount,
        currency: 'usd',
        card: args.token,   // stripe charge token generated by stripe.js
        description: args.user
      }
    });
    if (receipt.paid && receipt.amount >= amount) {
      // mark the user as paid in firebase
      return patch({
        url: 'https://vocowl.firebaseio.com/users/' + args.user + '.json?auth=' + firebase_authKey,
        body: JSON.stringify({paid: true})
      });
    } else {
      return receipt; // error happened or user paid less, let client handle it
    }
  }
};
  • On the client side, I used AngularJs and Firebase's angularFire plugin to sync my client side models with database changes in Firebase. This means when Webshell.io updates the user model in Firebase with the Stripe receipt, the changes get propagated immediately to client side.

  • Firebase has smart and configurable access control features that let's me do things like:

    • Only paid users can access the full features
    • Users cannot modify their own data except what is under user.settings and nor can they data about other users
    • Payment data can only be modified through the script I stored in Webshell.io using a private key I stored there
  • I can have some additional configuration in Webshell.io that prevents the app from accepting payments and in Firebase from accepting Persona auths unless app is hosted on localhost:8000 or *.github.io or vocowl.com.

Bitdeli Badge

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].