Skip to content
Browse files

Added the best API so far in facebook.alt.js and oauth.alt.js. Now, r…

…eads really nicely and seems like it could be nice architecturally.
  • Loading branch information...
1 parent 42f9f3d commit 31e6cb503bfb9fa398e9048a0f5a039182de5289 @bnoguchi committed Apr 5, 2011
Showing with 290 additions and 1 deletion.
  1. +106 −0 lib/facebook.alt.js
  2. +182 −0 lib/oauth.alt.js
  3. +2 −1 lib/oauth.js
View
106 lib/facebook.alt.js
@@ -0,0 +1,106 @@
+var oauthModule = require('./oauth');
+
+var fb = module.exports =
+oauthModule.submodule('facebook')
+ .apiHost('https://graph.facebook.com')
+ .configurable('scope')
+ .entryPath('/auth/facebook')
+ .callbackPath('/auth/facebook/callback')
+ .fetchOAuthUser( function (accessToken) {
+ this.oauth.getProtectedResource(this.apiHost() + '/me', accessToken, function (err, data, response) {
+ if (err) return p.error(err);
+ var oauthUser = JSON.parse(data);
+ p.fulfill(oauthUser);
+ })
+ })
+
+var fb = module.exports =
+oauthModule.submodule('facebook')
+ // TODO submodule should
+ // set fb.name = 'facebook'
+ .apiHost('https://graph.facebook.com')
+ .setters('scope')
+ .routeStep('authRequest')
+ .uri('/auth/facebook')
+ .step('authRequest')
+ .accepts('req res abc')
+ .returns('*')
+ .get('/auth/facebook')
+ // Should be able to access module
+ // properties from within a step
+ // definition
+ .step('authCallback')
+ .get('/auth/facebook/callback')
+ .step('addToSession')
+ .define( function (sess, auth) {
+
+ })
+
+// Introspection
+console.log( fb.steps );
+
+// Make order of steps explicit
+// fb.seq(...)
+fb.steps.order('authRequest', 'authCallback', 'addToSession');
+
+fb.step('authRequest').steps.order(
+ 'handleRequest', 'determineScope',
+ 'generateAuthUri', 'redirectToAuthUri');
+// `order(...)` should throw an error if it is missing a step
+
+
+
+
+
+
+
+
+
+
+////////////////////////////////////////
+
+function findUser (cred, fbUserMetadata) {
+ var p = new Promise();
+ User.find({id: 1}, function (err, user) {
+ p.succeed(err, user);
+ });
+ return p;
+}
+
+function orCreateUser(err, user) {
+ var p = new Promise();
+ if (user) {
+ p.succeed(null, user);
+ } else {
+ User.create({}, function (err, user) {
+ p.succeed(err, user);
+ });
+ }
+ return p;
+}
+
+function assignToSession (sess, user, cred, fbData) {
+ var p = new Promise();
+ // Logic goes here
+ p.succeed(sess, user, cred, fbData);
+ return p;
+}
+
+function anon (req, res, uid, cred, info) {}
+
+function anon2 (req, res, provider, uid, cred, info) {}
+
+everyauth(
+ function (req, res, provider, cred, info) {
+ }
+ , facebook(
+ function (req, res, uid, cred, info) {
+ }
+ , userLogic(
+ )
+ )
+ , twitter(
+ function (req, res, uid, cred, info) {
+ }
+ )
+);
View
182 lib/oauth.alt.js
@@ -0,0 +1,182 @@
+var everyModule = require('./everymodule')
+ , OAuth = require('oauth').OAuth2
+ , url = require('url');
+
+// Steps define a sequence of logic that pipes data through
+// a chain of promises. A new chain of promises is generated
+// every time the set of steps is started.
+
+var oauth = module.exports =
+everyModule.submodule('oauth')
+ .init( function () {
+ this.oauth = new OAuth(this.appId(), this.appSecret(), this.apiHost());
+ })
+ .configurable('apiHost appId appSecret myHostname')
+ .get('entryPath')
+ .step('getAuthUri')
+ .accepts('req res')
+ .promises('authUri')
+ .step('requestAuthUri')
+ .accepts('res authUri')
+ .promises(null)
+ .get('callbackPath')
+ .step('getCode')
+ .accepts('req res')
+ .promises('code')
+ .step('getTokens')
+ .accepts('code')
+ .promises('accessToken refreshToken')
+ .step('fetchOAuthUser')
+ .accepts('accessToken refreshToken')
+ .promises('user')
+ .step('getSession')
+ .accepts('req')
+ .promises('session')
+ .step('addToSession')
+ .accepts('session')
+ .promises(null)
+ .step('compile')
+ .accepts('accessToken refreshToken user')
+ .promises('auth')
+ .step('sendResponse')
+ .accepts('req res auth')
+ .promises(null)
+ .getAuthUri( function (req, res) {
+ var oauth = this._oauth
+ , authUri = oauth.getAuthorizeUrl({
+ redirect_uri: this._myHostname + this._callbackUri
+ , scope: scope});
+ return authUri;
+ })
+ .requestAuthUri( function (res, authUri) {
+ res.writeHead(303, {'Location': authUri});
+ res.end();
+ })
+ .getCode( function (req, res) {
+ var parsedUrl = url.parse(req.url, true);
+ return parsedUrl.query && parsedUrl.query.code;
+ })
+ .getTokens( function (code) {
+ var p = new Promise();
+ this.oauth.getOAuthAccessToken(code,
+ {redirect_uri: this.myHostname() + this.callbackUri()},
+ function (err, accessToken, refreshToken) {
+ if (err) return p.error(err);
+ p.fulfill(accessToken, refreshToken);
+ });
+ return p;
+ })
+ .getSession( function (req) {
+ return req.session;
+ })
+ .compile( function (accessToken, refreshToken, user) {
+ return {
+ accessToken
+ , refreshToken
+ , user
+ };
+ });
+
+// removeConfigurable
+// removeStep
+// undefinedSteps -> []
+// How about module specific and more generic addToSession? Perhaps just do addToSession with null
+
+
+
+var oauth = module.exports =
+everyModule.submodule('oauth')
+ .setters('apiHost entryUri callbackUri')
+ .setupRoutes( function (mod, app) {
+ app.get(mod._entryUri, mod.start('/auth/facebook'));
+ // mod.start() creates a new instantiation of the promise chain
+ // and returns the `trigger` of the first step
+ app.get(mod._callbackUri, mod.start('auth/facebook/callback'));
+ })
+ // Define a sequence of steps named 'auth/facebook'
+ .sequence('/auth/facebook')
+ .step('requestAuthUri', function (substep) {
+ substep('determineScope')
+ .accepts('req res')
+ .promises('scope')
+ .define(fn)
+ .error(fn);
+ substep('generateAuthUri')
+ .accepts('scope')
+ .promises('authUri');
+ substep('requestAuthUri')
+ .accepts('authUri')
+ .promises(null);
+ })
+ // reset vs bridge
+ // bridge should create a hook for
+ // instantiating a new chain of steps
+ .sequence('/auth/facebook/callback')
+ .step('retrieveCode')
+ .accepts('req res')
+ .promises('code')
+ .step('retrieveAccessToken')
+ .accepts('code')
+ .promises('accessToken refreshToken')
+ .step('getAuth')
+ .accepts('accessToken refreshToken')
+ .promises('auth');
+ // define can define the step function
+ // OR it can be the entry point for defining
+ // the sub steps it is composed of
+ .define( function (authRequest) {
+ authRequest
+ })
+ .step('authCallback')
+ .accepts('req res auth')
+ .promises(null);
+
+oauth.step('authRequest/determineScope').define( function (req, res) {
+ var scope = this._scope;
+ if ('function' === typeof scope) {
+ return scope(req);
+ }
+ return scope;
+});
+
+oauth.step('authRequest/generateAuthUri').define( function (scope) {
+ var oauth = this._oauth
+ , authUri = oauth.getAuthorizeUrl({
+ redirect_uri: this._myHostname + this._callbackUri
+ , scope: scope});
+ return authUri;
+});
+
+oauth.step('authRequest/retrieveCode').define( function (authUri) {
+ var res = this.cache.res;
+ res.writeHead(303, {'Location': authUri});
+ res.end();
+});
+
+
+// How to add steps to a module or to a composed step
+
+// Adds a series of steps
+oauth.step('authCallback', function (step) {
+ step('addCronJob');
+});
+
+// Adds a single step
+oauth.step('authCallback');
+
+// Over-rides a sequence of substeps
+// composedOf vs override
+oauth.step('authCallback').override(function (step) {
+ step(...);
+});
+
+oauth.step('authCallback').order('...');
+
+oauth.step('authCallback').addStep('addCronJob');
+
+oauth.step('authCallback').steps.order(...);
+
+oauth.step('authCallback').steps.add('addCronJob', {before: ''});
+
+oauth.step('authCallback').steps.add('addCronJob', {after: ''});
+
View
3 lib/oauth.js
@@ -12,7 +12,8 @@ var everyModule = require('./everymodule')
// // Automatically comes with uri and/or handler replacing
// // capabilities
//
-var oauthModule = module.exports = everyModule.submodule({
+var oauthModule = module.exports =
+everyModule.submodule({
setters: 'apiHost appId appSecret callbackUri fetchOAuthUser myHostname'
, on: {
'set.callbackUri': function (strategy, uri) {

0 comments on commit 31e6cb5

Please sign in to comment.
Something went wrong with that request. Please try again.