Пример #1
0
exports.get = function( done ){

  if (!cachedGetResults){

    // Simple schema
    var BasicSchema =  declare( [ SimpleSchema, hotplate.config.get( 'hotplate.SchemaMixin') ] );

    // Sets the DB Layer
    var DbLayer = declare([ SimpleDbLayer, hotplate.config.get('hotplate.DbLayerMixin') ], {
      db: hotplate.config.get( 'hotplate.db' )
    });

      // Creates a basic DB store based on that layer
    var BasicDbStore = declare( [ JsonRestStores, JsonRestStores.SimpleDbLayerMixin, JsonRestStores.HTTPMixin ], {
      DbLayer: DbLayer,
      chainErrors: 'all'
    });

    // Legacy names
    var HotSchema = BasicSchema;
    var HotStore = BasicDbStore;

    cachedGetResults = { DbLayer, BasicSchema, HotSchema, BasicDbStore, HotStore }
  }

  if( done ) return done( null, cachedGetResults );
  else return( cachedGetResults );
};
Пример #2
0
hotplate.hotEvents.on( 'setRoutes', hotplate.cachable( function( app, done ){

   // Pages
  app.get(  path.join( hotplate.config.get( 'hotplate.routeUrlsPrefix' ), '/auth/welcome' ) , pageWelcome);
  app.get(  path.join( hotplate.config.get( 'hotplate.routeUrlsPrefix' ), '/auth/pick' ) , pagePick );

  done( null );
}));
Пример #3
0
hotplate.hotEvents.on( 'pageElements', 'hotCoreMultiHome', function( done ){

  done( null, {
    vars:  [
             { name: 'enabled',      value: hotplate.config.get('hotCoreMultiHome.enabled') },
             { name: 'multiHomeURL', value: hotplate.config.get('hotCoreMultiHome.multiHomeURL') },
           ],
  });
});
Пример #4
0
hotplate.hotEvents.on( 'pageElements', 'hotCoreAuth', function( done ){
  var strategyIds = Object.keys( hotplate.config.get('hotCoreAuth.strategies') ) || [];
  
  done( null, {
    vars: [
            { name: 'strategyIds',  value: strategyIds },
            { name: 'successURLs',  value: hotplate.config.get('hotCoreAuth.redirectURLs.success') },
            { name: 'failURLs',     value: hotplate.config.get('hotCoreAuth.redirectURLs.fail') },
          ],
  });
});
Пример #5
0
hotplate.hotEvents.on( 'setRoutes', hotplate.cachable( function( app, done ){

  // Set the multiHome page, or the straight one
  if( hotplate.config.get('hotCoreMultiHome.enabled' ) ){
    app.get( hotplate.config.get('hotCoreMultiHome.multiHomeURL'), mainApp );
  } else {
    app.get( hotplate.config.get('hotCoreAuth.appURL'), mainApp);
  }

  done( null );
})); 
Пример #6
0
  function restOfTheFunction(){ 

    hotCorePage.processPageTemplate(
    {
      vars: (new hotCorePage.Vars() ).add( 'hotDojoAppContainer', { 
        name: 'failURLs', 
        value: hotplate.config.get('hotCoreAuth.redirectURLs.fail')
      }),
      csses: (new hotCorePage.Csses() ).add( 'hotDojoAppContainer', 'mainContainer.css' ),
      bodyLines: (new hotCorePage.BodyLines() ).add( 'hotDojoAppContainer', '<div id="appContainer"></div>' ),
    },
    req, 
    'hotDojoAppContainer/container',
    function( err, result ){ 
      if( err ){
        next( err );
        logger.log( { message: "ERROR while App container page served" } );
      } else {
        res.send( result );
        logger.log( { message: "App container page served" } );
      }
    }
    );
    return;
  }
Пример #7
0
 app.get( hotplate.prefix( '/auth/register/facebook/web' ), function( req, res, next ){
   var callbackURLBase = hotplate.config.get( 'hotCoreAuth.callbackURLBase' );
   if( typeof callbackURLBase === 'function') {
     callbackURLBase = callbackURLBase( req );
   }
   var callbackURL = callbackURLBase + hotplate.prefix( "/auth/register/facebook/callback" )
   passport.authenticate('facebook-register',  { scope: strategyConfig.profileScope || DEFAULT_SCOPE, callbackURL: callbackURL } )( req, res, next );
 });
Пример #8
0
      allStores.usersWorkspaces.apiGetQuery( { filters: { userId: req.session.userId  }  }, function( err, records ){
        if( err ){
          next( err );
        }  else {
        
          // To escape picking, there needs to be exactly 1 workspace AND escapePick needs to be true
          if( records.length !== 1 || ! hotplate.config.get( 'hotCoreMultiHome.escapePick' ) ){
            returnThePage();

          // OK, escape successful! Get the application URL and jump there
          } else {
            var applicationURL = hotplate.config.get( 'hotCoreMultiHome.multiHomeURL' );
            applicationURL = applicationURL.replace( ':workspaceId', records[0].workspaceId );
            res.redirect( applicationURL );
          } 
        }
      });
Пример #9
0
            function( partInStruct, cb ){

              // Get the filename, Use DeepObject as it's quite deep into partInStruct
              var fileName = DeepObject.get( partInStruct, 'disposition.params.filename');

              // Get the size limit from the configuration
              var sizeLimit = hotplate.config.get('hotCoreTransport.activeTransports.email-default.attachmentSizeLimit');


              debug("sizeLimit is: ", sizeLimit );
;
              debug("Comparing: %d && %d > %d", sizeLimit, partInStruct.size, sizeLimit );

              // If it's too big, do not download it
              if( sizeLimit && partInStruct.size > sizeLimit ){
                // The next log line is pointless as the message hasn't been created yet, and it
                // would end up in the "generic" transport log...
                // logLine( config, null, null, 1, "Attachment " + fileName + " wasn't fetched as it was too big --  " + partInStruct.size + " bytes against a " + sizeLimit + "limit" );

                // Make up the attachment object
                var p = {
                  id: partInStruct.partID,
                  mimeType: partInStruct.type+ '/' + partInStruct.subtype,
                  retrieved: false,
                  size: partInStruct.size,
                };
                if( fileName ) p.fileName = fileName;
                if( partInStruct.id ) p.embeddedId = partInStruct.id;

                // Add the object to the attachment array
                fullImapMessage.attachments.push( p );

                return cb( null );
              }

              debug("ABOUT TO FETCH ATTACHMENT PART %o:", partInStruct);
              fetchMessagePart( imap, fullImapMessage.uid, partInStruct.partID, function( err, downloadedPart ){
                if( err ) return cb( err );

                //downloadedPart.body = downloadedPart.body.substr( 0, 400 );
                debug("ATTACHMENT PART FETCHED:", downloadedPart );

                // Make up the attachment object
                var p = {
                  id: partInStruct.partID,
                  data: downloadedPart.body,
                  mimeType: partInStruct.type+ '/' + partInStruct.subtype,
                  size: partInStruct.size,
                  retrieved: true,
                };
                if( fileName ) p.fileName = fileName;
                if( partInStruct.id ) p.embeddedId = partInStruct.id;

                // Add the object to the attachment array
                fullImapMessage.attachments.push( p );
                cb( null );
              })
            },
Пример #10
0
var pagePick = function( req, res, next ){

  if( req.session.loggedIn){

    var allStores = hotCoreStoreRegistry.getAllStores( function( err, allStores ){

      allStores.usersWorkspaces.apiGetQuery( { filters: { userId: req.session.userId  }  }, function( err, records ){
        if( err ){
          next( err );
        }  else {
        
          // To escape picking, there needs to be exactly 1 workspace AND escapePick needs to be true
          if( records.length !== 1 || ! hotplate.config.get( 'hotCoreMultiHome.escapePick' ) ){
            returnThePage();

          // OK, escape successful! Get the application URL and jump there
          } else {
            var applicationURL = hotplate.config.get( 'hotCoreMultiHome.multiHomeURL' );
            applicationURL = applicationURL.replace( ':workspaceId', records[0].workspaceId );
            res.redirect( applicationURL );
          } 
        }
      });
      
   
      function returnThePage(){

        hotCorePage.processPageTemplate(
          {
            csses: (new hotCorePage.Csses() ).add( 'hotDojoAuth', 'pick.css' ),
            vars: (new hotCorePage.Vars() ).add( 'hotDojoAuth', 'pick.css' ),
            bodyLines: (new hotCorePage.BodyLines() ).add( 'hotDojoAuth', '<div data-dojo-type="hotplate/hotDojoAuth/Pick" id="pick">' ),
          },
          req,
          'hotDojoAuth/Pick',
          function( err, result ){
            if( err ){
              next( err );
            } else {
              res.send( result );
              logger.log( { message: "Pick page served" } );
            }
          }
        );
        return;
      }
    });

  } else {

    var redirectURLs = hotplate.config.get( 'hotCoreAuth.redirectURLs.fail' );
    var redirectURL = redirectURLs[ 'signin' ] || '/' ;
    res.redirect( redirectURL );

  }

};
Пример #11
0
     Object.keys( hotplate.config.get('hotCoreAuth.strategies' )).forEach( function( strategyName ) {
     
       // Get the strategy's data
       var strategyConfig = hotplate.config.get('hotCoreAuth.strategies' )[strategyName];
 
       // Gets the right strategy maker and runs it
       var strategyMaker = require( './auth/' + strategyName );
       strategyMaker( app, strategyConfig, makeResponder, stores.authStrategies, stores.users, stores.usersStrategies, stores.logins );
     });
Пример #12
0
 execGetDbQuery: function( request, cb ){
   var strategies = hotplate.config.get('hotCoreAuth.strategies');
   var doc;
   var docs = [];
   
   for( var strategyId in strategies ){
     docs.push( { id: strategyId } );
   }      
   cb( null, docs );
 },
Пример #13
0
    app.get( hotplate.prefix( '/auth/signin/facebook/callback' ), function( req, res, next) {

      // Why callbackURL is mandatory IN THE CALLBACK escapes me...
      var callbackURLBase = hotplate.config.get( 'hotCoreAuth.callbackURLBase' );
      if( typeof callbackURLBase === 'function') {
        callbackURLBase = callbackURLBase( req );
      }
      var callbackURL = callbackURLBase + hotplate.prefix( "/auth/signin/facebook/callback" );
      passport.authenticate('facebook-signin',  { callbackURL: callbackURL }, makeResponder( req, res, next, 'facebook', 'signin')  )(req, res, next);
    });
Пример #14
0
  stores.tabs.dbLayer.selectById(tabId, function (err, record) {
    if (err) return cb(err)

    if (record) {
      consolelog('tabId already there, nothing to add')
      return cb(null, false)
    }

    consolelog('Before adding tabId to the db, adding the Subscriptions...')
    var makeDefaultSubscriptions = hotplate.config.get('hotCoreComet.makeDefaultSubscriptions')
    makeDefaultSubscriptions(ws.upgradeReq, tabId, sessionData, function (err, defaultSubscriptions) {
      if (err) return cb(err)

      consolelog('Default subscriptions:', defaultSubscriptions)

      async.eachSeries(
        defaultSubscriptions,

        function (subscription, cb) {
          consolelog('Adding subscription: ', subscription)

          subscription.tabId = tabId
          subscription.hash = makeSubscriptionHash(subscription)
          stores.tabSubscriptions.dbLayer.insert(subscription, function (err, record) {
            if (err) return cb(err)

            return cb(null)
          })
        },

        function (err) {
          if (err) {
            consolelog('There was an error trying to add subscriptions. Deleting the ones already added, and quitting')
            stores.tabSubscriptions.dbLayer.deleteByHash({ tabId: tabId }, function (err, record) {
              if (err) consolelog('Error deleting pending after error creating subscriptions', tabId, err)
            })
            return cb(err)
          }

          consolelog('Adding tabId to the db...')
          stores.tabs.dbLayer.insert({ id: tabId }, function (err, record) {
            if (err) {
              consolelog('There was an error trying to add the tab. Deleting the ones already added, and quitting')
              stores.tabSubscriptions.dbLayer.deleteByHash({ tabId: tabId }, function (err, record) {
                if (err) consolelog('Error deleting pending after error creating tab', tabId, err)
              })
              return cb(err)
            }

            cb(null, true)
          })
        }
      )
    })
  })
Пример #15
0
exports.hotCoreErrorHandler = function( err, req, res, next){

  var accept = req.headers.accept || '';
  var env = process.env.NODE_ENV || 'development';

  // Print the stack to console in any case
  if( env !== 'test' && err.stack ) console.error( err.stack );

  // It's not an HTTP error: make a "system" log entry for it, as this
  // should never ever happen. This entry will be on TOP of the "normal" entry
  // (which the user will be able to see)
  if( typeof( e[ err.name ] ) === 'undefined' ){
    // Log the error
    logger.log({
      logLevel     : 5,
      errorName    : err.name,
      message      : err.message,
      errors       : [],
      system       : true,
      data         : { error: err, trace: err.stack },
    });
  }

  // It's not an HTTP error: make up a new one, and incapsulate original error in it
  if( typeof( e[ err.name ] ) === 'undefined'  ){
    err = new e.ServiceUnavailableError( { originalErr: err, originalErrName: err.name, originalErrMessage: err.message } );
  }

  // Log the error, in 
  logger.log({
    logLevel     : err.logLevel || 3,
    errorName    : err.name,
    message      : err.message,
    errors       : err.errors || [],
    system       : false,
    data         : { error: err },
  });

  // If it was an HTML page that generated the error, return hotplate's error page
  if( ~accept.indexOf('html') ){
    req.hotError = err; // FIXME
    hotplate.config.get('hotCoreError.errorPage')(req, res, next);    

  // If it was a JSON request, do a sendResponse following the protocol
  } else if (~accept.indexOf('json') || ~accept.indexOf('*/*') ) {
    sendResponse( res, { message: err.message, errors: err.errors }, err.httpError );

  // Otherwise, just print the output out...
  } else {
    res.writeHead(err.httpError, { 'Content-Type': 'text/plain' });
    res.end( err.message );
  }  
  
}
Пример #16
0
    Object.keys( allStores ).forEach( function( storeName ){

      var store = allStores[ storeName ];

      // The store has a public URL: add it to the list of stores to expose
      // Note that I pass the modified URL to setAllRoutes
      if( store.hotExpose ){
        store.publicURLPrefix = hotplate.config.get( 'hotCoreStore.storesUrlsPrefix' );
        store.protocolListenHTTP( { app: app } );
      }
    });
Пример #17
0
    Object.keys( registry.stores ).forEach( function( storeName ){
      var storeEntry = registry.stores[ storeName ];

      var Store = storeEntry.Store;
      var storeObject = storeEntry.storeObject;
  
      if( storeObject.publicURL && storeObject.hotExpose ){
        var url = path.join( hotplate.config.get( 'hotCoreStoreExposer.storesUrlsPrefix' ), storeObject.publicURL );
        stores[ storeObject.storeName ] = { target: url, sortParam: 'sortBy'  };
      }
    });
Пример #18
0
    Object.keys( allStores ).forEach( function( storeName ){
      
      var store = allStores[ storeName ];

      // The store has a public URL: add it to the list of stores to expose
      // Note that I pass the modified URL to setAllRoutes
      if( store.hotExpose ){
        var url = path.join( hotplate.config.get( 'hotCoreStoreExposer.storesUrlsPrefix' ), store.publicURL );
        store.setAllRoutes( app, url );
      }
    });
Пример #19
0
hotplate.hotEvents.on( 'setRoutes', hotplate.cachable( function( app, done ){

  // Defines the route [moduleFilesPrefix]/hotCoreSharedCode/shares.js which will
  // return the javascript which will define an object variable called
  // sharedFunctions containing all the defined validation functions
  // (divided by module)
  var sharedFunctionsLocation = path.join( hotplate.config.get('hotplate.moduleFilesPrefix'), 'hotCoreSharedCode', 'shared.js');


  hotplate.hotEvents.emit( 'sharedFunctions', function( err, sharedFunctions ){
    if( err ){
      done( err );
    } else {

      app.get( sharedFunctionsLocation, function( req, res ){
        var result = '';

        // Define the variable as an associative array
        // WATCH OUT: needs to end with "\n " so that comma-clipping works even
        // if there is nothing in the rendered object
        result += "var sharedFunctions = { \n ";
    
        // Cycle through every module defined...
        sharedFunctions.forEach( function( item ){
          var moduleName = item.module;
          var sharedFunctions = item.result;

          // WATCH OUT: needs to end with "\n " so that comma-clipping works even
          // if there is nothing in the rendered object
          result += moduleName + ": {\n ";
          for( var functionName in sharedFunctions ){
            if( typeof( sharedFunctions[ functionName ] ) === 'function' ){
              result += functionName + ": " + sharedFunctions[ functionName ] + ",\n";
            }
          }
          // Clip the last comma and close the variable
          result = result.substring( 0, result.length -2 ) + "\n";
          result += "},\n";
        });

        // Clip the last comma and close the main associative array
        result = result.substring( 0, result.length -2 ) + "\n";
        result += "}\n";

        res.send( result );
      });

      done( null );
    }
  });

}))
Пример #20
0
 allStores.stores.WorkspacesUsers.Store.GetQuery( { filters: { workspaceId: req.params.workspaceId, userId: req.session.userId } }, function( err, wsRecords ){
   if( err ){
     next( err );
   } else {
     // Not allowed: knocked back.
     if( wsRecords.length !== 1 ){
       res.redirect( hotplate.config.get('hotCoreAuth.redirectURLs.fail.signin') );
     } else {
       // All good, the page CAN be served!
       restOfTheFunction();
     }
   }
 });
Пример #21
0
               stores.users.apiPut( user.id, user, { killComet: true }, function( err, userNew ){
                 if( err ){
                   next( err );
                 } else {
 
                   // Log the user in using the token!
                   req.session.loggedIn = true;
                   req.session.userId = user.id;
 
                   // Redirect to the right URL
                   res.redirect( hotplate.config.get('hotCoreAuth.redirectURLs.success.recover') );
                 }
   
               });
Пример #22
0
    Object.keys( allStores ).forEach( function( storeName ){
      var store = allStores[ storeName ];

      if( store.publicURL && store.hotExpose ){
        var url = path.join( hotplate.config.get( 'hotCoreStoreExposer.storesUrlsPrefix' ), store.publicURL );
        storesVarsData[ store.storeName ] = { 
          target: url,
          sortParam: 'sortBy',
          alsoNotify: store.alsoNotify,
          enabledField: store.enabledField,
          defaultNewToStart: store.defaultNewToStart,
          type: store.type ? store.type : 'cached',
        };
      }
    });
Пример #23
0
     execAllDbFetch: function( request, cb ){
       var strategies = hotplate.config.get('hotCoreAuth.strategies');
       var doc;
 
       // No strategies defined in Hotplate, end of story
       if( typeof( strategies ) === 'undefined' ){
         return cb( null, null );     
       }
  
       // Check if the strategy is one of the ones defined in Hotplate
       if( typeof( strategies[ params.id ] ) !== 'undefined' ){
         doc = {}
         doc.id = params.id;
       } else {
         doc = null;
       }
 
       // Return whatever was found
       cb( null, doc );
     },
Пример #24
0
        _broadcast: function( killCometOption, type, objectId, object, options ){

          var makeTabIdHash;
          var fromUserId;
          var storeTarget;

          // No comet required (from the option, or for the store's own request
          if( this.killComet || killCometOption ) return;

          // Sets the userId if it's a remote request
          if( this.remote ){
             fromUserId = this._req.session.userId;
          } else {
             fromUserId = null;
          }

          // If it's in a multi-home environment, use the specific multi-home filter
          // if( hotplate.config.get( 'hotCoreMultiHome.enabled' ) && object.workspaceId ) makeTabIdHash = exports.makeTabIdHashForMultihome;
          if( hotplate.config.get( 'hotCoreMultiHome.enabled' ) ) makeTabIdHash = hotCoreMultiHome.makeTabIdHashForMultihome;

          var message = { type: type, storeName: this.storeName, objectId: objectId, object: object };

          // If options.beforeId is set, make up a fake record with 'before' set as record with matching ID is idProperty
          // We cannot really send the whole record as we never fetch it fully
          if( options.beforeId ){
            if( options.beforeId === 'null' ){
              message.before = null;
            } else {
              message.before = {};
              message.before[ this.idProperty ] = options.beforeId;
            }
          }
          if( options.relocation) message.relocation = true;

          // Actually invoke the broadcast
          hotplate.hotEvents.emit('cometBroadcast', fromUserId, this._getTabId(), makeTabIdHash, message,  function(){}  );

        },
Пример #25
0
  hotplate.hotEvents.emit('sharedFunctions', function( err, sharedFunctions) {
    if( err ){
      done( err );
    } else {

      // Gets the results, and adds them to the sharedValidators hash which
      // will then get used
      sharedFunctions.onlyResults().forEach( function( functions ){
        for( var k in functions ){
          // If it ends with "Validator", then it's a validator
          if( k.indexOf('Validator', k.length - 'Validator'.length) !== -1 ){
            sharedValidators[ k ] = functions[ k ];
          }
        }
      });

      classes.HotSchemaMixin = declare( null, {

        sharedValidatorTypeParam: function( p ){
          if( typeof( p.parameterValue ) !== 'string' )
            throw( new Error("Validator needs to be a string, found: " + typeof( p.parameterValue ) ) );

     
          var f = sharedValidators[ p.parameterValue + "Validator" ];
 
          if( f && ! f( p.value ) ){
            var msg = f( false );
            p.errors.push( { field: p.fieldName, message: msg, mustChange: true } );
          }
        }
      });

      classes.HotSchema = declare( [ SimpleSchema, hotplate.config.get( 'hotplate.SchemaMixin'), classes.HotSchemaMixin ] );

      classes.HotStoreMixin = declare( null, {

        killComet: false,
        chainErrors: 'all',

        hotGlobalBroadcast: false,

        echoAfterPutNew: true,
        echoAfterPutExisting: true,
        echoAfterPost: true,

        logError: function( error ){
          hotCoreServerLogger.log( error );
        },

        _getTabId: function( req ){

          // If the tab header wasn't there, then there is no way to broadcast -- abord
          if( typeof( this._req ) === 'undefined' ) return null;

          var tabId = this._req.headers['x-hotplate-tabid'];
          if( tabId == '' ){
            tabId = null;
          }
          return tabId; 
        },


        _broadcast: function( killCometOption, type, objectId, object, options ){

          var makeTabIdHash;
          var fromUserId;
          var storeTarget;

          // No comet required (from the option, or for the store's own request
          if( this.killComet || killCometOption ) return;

          // fromUserId taken from the session (if it exists) or set to null (it's an API call)
          fromUserId = ( this._req && this._req.session && this._req.session.userId ) || null;

          // If it's in a multi-home environment, use the specific multi-home filter
          // if( hotplate.config.get( 'hotCoreMultiHome.enabled' ) && object.workspaceId ) makeTabIdHash = exports.makeTabIdHashForMultihome;
          if( hotplate.config.get( 'hotCoreMultiHome.enabled' ) ) makeTabIdHash = hotCoreMultiHome.makeTabIdHashForMultihome;

          var message = { type: type, storeName: this.storeName, objectId: objectId, object: object };

          // If options.beforeId is set, make up a fake record with 'before' set as record with matching ID is idProperty
          // We cannot really send the whole record as we never fetch it fully
          if( options.beforeId ){
            if( options.beforeId === 'null' ){
              message.before = null;
            } else {
              message.before = {};
              message.before[ this.idProperty ] = options.beforeId;
            }
          }
          if( options.justReposition) message.justReposition = true;

          // Actually invoke the broadcast
          hotplate.hotEvents.emit('cometBroadcast', fromUserId, this._getTabId(), makeTabIdHash, message,  function(){}  );


          /*
            // What follows is the attempt to send a comet message for every store that uses the _collection_ modified by the
            // change. Unfortunately, sub-stores that change a subset of the data effectively cannot be done because
            // the comet message would be incomplete (it would only have some of the fields).


          hotCoreStoreRegistry.getAllStores( function( err, allStores ){


            allStores.collections[ self.collectionName ].forEach( function( s ){

              console.log("Setting up a message for ", s.storeObject.storeName );
              var message = { type: type, storeName: s.storeObject.storeName, objectId: objectId, object: object };
              console.log("The message is: ", message );

              // If options.beforeId is set, make up a fake record with 'before' set as record with matching ID is idProperty
              // We cannot really send the whole record as we never fetch it fully
              if( options.beforeId ){
                if( options.beforeId === 'null' ){
                  message.before = null;
                } else {
                  message.before = {};
                  message.before[ this.idProperty ] = options.beforeId;
                }
              }
              if( options.justReposition) message.justReposition = true;

              // Actually invoke the broadcast
              hotplate.hotEvents.emit('cometBroadcast', fromUserId, self._getTabId(), makeTabIdHash, message,  function(){}  );

            });

          } );
          */


        },

        afterPutExisting: function afterPutExisting( params, body, options, doc, fullDoc, docAfter, fullDocAfter, overwrite, done ){
          var self = this;


          this.inheritedAsync( afterPutExisting, arguments, function(){

            self._broadcast( options.killComet, 'storeRecordUpdate', docAfter[ self.idProperty], docAfter, options );
            done( null );
          });
        },    

        afterPost: function afterPost( params, body, options, doc, fullDoc, done ){
          var self = this;
          this.inheritedAsync( afterPost, arguments, function(){
            self._broadcast( options.killComet, 'storeRecordCreate', doc[ self.idProperty], doc, options );
            done( null );
          });
        },

        afterPutNew: function afterPutNew( params, body, options, doc, fullDoc, overwrite, done ){
          var self = this;
          this.inheritedAsync( afterPutNew, arguments, function(){
            self._broadcast( options.killComet, 'storeRecordCreate', doc[ self.idProperty], doc, options );
            done( null );
          });
        },

        afterDelete: function afterDelete( params, body, options, doc, fullDoc, done ){
          var self = this;
          this.inheritedAsync( afterDelete, arguments, function(){
            self._broadcast( options.killComet, 'storeRecordRemove', doc[ self.idProperty ], doc, options ); 
            done( null );
          });
        },    
      });

      classes.HotStore = declare( [ JsonRestStores, classes.HotStoreMixin ],{
        DbLayer: declare( [ SimpleDbLayer, hotplate.config.get('hotplate.DbLayerMixin') ], { db: hotplate.config.get( 'hotplate.db' ) } )
      });

      done( null, classes );

    }
  });
Пример #26
0
var dummy
  , hotplate = require('hotplate')

  , e = require('allhttperrors')

  , logger = require('hotCoreServerLogger')
  , sendResponse = require('hotCoreErrorProtocol').sendResponse
;

// Set some sane defaults

hotplate.config.set('hotCoreError.errorPage', function( req, res, next ){

  var errorString = "ERROR: " + req.hotError + ", NAME: " + req.hotError.name;
  var httpError = req.hotError ? req.hotError.httpError : 200;

  res.send( httpError, errorString + " -- CUSTOMISE YOUR ERROR PAGE BY SETTING hotCoreError.errorPage IN YOUR SERVER FILE" );
});


// Sets logLEvels for errors, _and_ sets some more friendly defaults in terms of messages etc.

Object.keys( e ).forEach( function( o ){

  var proto = e[ o ].prototype;

  switch( o ){
    case 'ServiceUnavailableError':
      proto.logLevel = 5;
      proto.message = "Server error";
Пример #27
0
exports = module.exports = function( app, strategyConfig,  makeResponder, AuthStrategies, Users, UserStrategies, UserLogins ) {

  // Work out callbackURLBase which needs to be honoured
  var callbackURLBase = hotplate.config.get( 'hotCoreAuth.callbackURLBase' );

  // ***********************
  // *** MANAGER         ***
  // ***********************

  passport.use('facebook-manager', new FacebookStrategy({
    clientID: strategyConfig.clientID,
    clientSecret: strategyConfig.clientSecret,
    callbackURL: callbackURLBase + "/auth/manager/facebook/callback",
    passReqToCallback: true,
  },

  function(req, accessToken, refreshToken, profile, done) {


    if( ! req.session.loggedIn ){
      done( null, false );
    } else {

      // The profile MUST contain an ID
      if( typeof( profile ) === 'undefined' || ! profile.id ){ 
         return done( null, false, { message: "Facebook didn't return a profile ID, procedure aborted" } );
      }

      // Check that "facebook" isn't already there
      UserStrategies.GetQuery( { filters: { userId: req.session.userId, strategyId: 'facebook' } }, function( err, res ){
        if( err ) {
          done( err, null );
        } else {
          if( res.length ){
            done( null, false, { message: "User already has a Facebook login setup" } );
          } else {
            
            // Check that "facebook" isn't already there
            UserStrategies.GetQuery( { filters: { field1: profile.id } }, function( err, res ){
              if( err ) {
                done( err, null );
              } else {
                if( res.length ){
                  done( null, false, { message: "Facebook profile already linked to another account" } );
                } else {

                  UserStrategies.Post( { userId: req.session.userId, strategyId: 'facebook', field1: profile.id }, function( err, res ){
                    if( err ) {
                      done( err, null );
                    } else {
                      Users.Get( req.session.userId, function( err, user ){
                        if( err ){
                          done( err, null );
                        } else {
                          done( null, user, profile  );
                        }
                      });
                    }
                  });

                }
              }
           });
            
          } 
        }
      });
    }
  }
  ));

  app.get('/auth/manager/facebook', passport.authenticate('facebook-manager'));
  app.get('/auth/manager/facebook/callback', function( req, res, next) {
    passport.authenticate('facebook-manager',  makeResponder( req, res, next, 'facebook', 'manager')  )(req, res, next);
  });


  // ***********************
  // *** SIGN IN         ***
  // ***********************

  passport.use('facebook-signin', new FacebookStrategy({
    clientID: strategyConfig.clientID,
    clientSecret: strategyConfig.clientSecret,
    callbackURL: callbackURLBase + "/auth/signin/facebook/callback",
    passReqToCallback: true,
  },

  function(req, accessToken, refreshToken, profile, done) {

    if( req.session.loggedIn ){
      done( null, false );
    } else {

      // The profile MUST contain an ID
      if( typeof( profile ) === 'undefined' || ! profile.id ){ 
         return done( null, false, { message: "Facebook didn't return a profile ID, procedure aborted" } );
      }

      UserStrategies.GetQuery( { filters: { strategyId: 'facebook', field1: profile.id } }, function( err, res ){
        if( err ) {
          done( err, null );
        } else {

          if( res.length ){
            Users.Get( res[0].userId, function( err, user ){
              if( err ){
                done( err, null );
              } else {
                req.session.loggedIn = true;
                req.session.userId = user.id;
                done( null, user, profile  );
              }
            });

          } else {
            done( null, false, { message: "Your Facebook user is not registered" } );
          }
        }
      });

    }

    // done( null, false );
  }
  ));

  app.get('/auth/signin/facebook', passport.authenticate('facebook-signin'));
  app.get('/auth/signin/facebook/callback', function( req, res, next) {
    passport.authenticate('facebook-signin',  makeResponder( req, res, next, 'facebook', 'signin')  )(req, res, next);
  });

  // ***********************
  // *** RECOVER         ***
  // ***********************

  passport.use('facebook-recover', new FacebookStrategy({
    clientID: strategyConfig.clientID,
    clientSecret: strategyConfig.clientSecret,
    callbackURL: callbackURLBase + "/auth/recover/facebook/callback",
    passReqToCallback: true,
  },

  function(req, accessToken, refreshToken, profile, done) {

    if( req.session.loggedIn ){
      done( null, false );
    } else {

      // The profile MUST contain an ID
      if( typeof( profile ) === 'undefined' || ! profile.id ){ 
         return done( null, false, { message: "Facebook didn't return a profile ID, procedure aborted" } );
      }

      UserStrategies.GetQuery( { filters: { strategyId: 'facebook', field1: profile.id } }, function( err, res ){
        if( err ) {
          done( err, null );
        } else {

          if( res.length ){
            Users.Get( res[0].userId, function( err, user ){
              if( err ){
                done( err, null );
              } else {
                // RECOVER PROCEDURE
                
                // Create the recoveryToken
                user.recoverToken = hat();
                user.recoverTokenCreated = new Date();

                // Place the token in the user's record
                Users.Put( user.id, user, { killComet: true }, function( err, newUser ){
                  if( err ){
                    done( err, null );
                  } else {
                    done( null, false, { message: "Recovery procedure initiated" }  );
                  }
                } );

              }
            });
          } else {
            done( null, false, { message: "Your Facebook user is not registered" } );
          }
        }
      });


    }

  }
  ));

  app.get('/auth/recover/facebook', passport.authenticate('facebook-recover'));
  app.get('/auth/recover/facebook/callback', function( req, res, next) {
    passport.authenticate('facebook-recover',  makeResponder( req, res, next, 'facebook', 'recover')  )(req, res, next);
  });


  // ***********************
  // *** REGISTER        ***
  // ***********************

  passport.use('facebook-register', new FacebookStrategy({
    clientID: strategyConfig.clientID,
    clientSecret: strategyConfig.clientSecret,
    callbackURL: callbackURLBase + "/auth/register/facebook/callback",
    passReqToCallback: true,
  },

  function(req, accessToken, refreshToken, profile, done) {

    if( req.session.loggedIn ){
      done( null, false );
    } else {

      // The profile MUST contain an ID
      if( typeof( profile ) === 'undefined' || ! profile.id ){ 
         return done( null, false, { message: "Facebook didn't return a profile ID, procedure aborted" } );
      }

      // Check that "facebook" isn't already there
      UserStrategies.GetQuery( { filters: { strategyId: 'facebook', field1: profile.id } }, function( err, res ){
        if( err ) {
          done( err, null );
        } else {
          if( res.length ){
            done( null, false, { message: "Facebook profile already registered" } );
          } else {
            Users.Post( { }, { killComet: true }, function( err, user ){

              if( err ){
                done( err, null );
              } else {

                UserStrategies.Post( { userId: user.id, strategyId: 'facebook', field1: profile.id }, { killComet: true}, function( err, res ){
                  if( err ) {
                    done( err, null );
                  } else {

                    // User just registered: make her "logged in"
                    req.session.loggedIn = true;
                    req.session.userId = res.userId;

                    done( null, user, profile );
                  }

                });
              }

            });

          } 
        }
      });
    }

  }
  ));

  app.get('/auth/register/facebook', passport.authenticate('facebook-register'));
  app.get('/auth/register/facebook/callback', function( req, res, next) {
    passport.authenticate('facebook-register',  makeResponder( req, res, next, 'facebook', 'register')  )(req, res, next);
  });



  // ***********************
  // *** RESUME          ***
  // ***********************

  passport.use('facebook-resume', new FacebookStrategy({
    clientID: strategyConfig.clientID,
    clientSecret: strategyConfig.clientSecret,
    callbackURL: callbackURLBase + "/auth/resume/facebook/callback",
    passReqToCallback: true,
  },

  function(req, accessToken, refreshToken, profile, done) {

    if( req.session.loggedIn ){
      done( null, false );
    } else {

      // The profile MUST contain an ID
      if( typeof( profile ) === 'undefined' || ! profile.id ){ 
         return done( null, false, { message: "Facebook didn't return a profile ID, procedure aborted" } );
      }

      UserStrategies.GetQuery( { filters: { strategyId: 'facebook', field1: profile.id } }, function( err, res ){
        if( err ) {
          done( err, null );
        } else {

          if( res.length ){
            Users.Get( res[0].userId, function( err, user ){
              if( err ){
                done( err, null );
              } else {
                req.session.loggedIn = true;
                req.session.userId = user.id;
                profile.message = "Logged back in!";

                done( null, user, profile  );
              }
            });

          } else {
            done( null, false, { message: "Your Facebook user is not registered" } );
          }
        }
      });

    }

    // done( null, false );
  }
  ));

  app.get('/auth/resume/facebook', passport.authenticate('facebook-resume'));
  app.get('/auth/resume/facebook/callback', function( req, res, next) {
    passport.authenticate('facebook-resume',  makeResponder( req, res, next, 'facebook', 'resume')  )(req, res, next);
  });


} 
Пример #28
0
        _broadcast: function( killCometOption, type, objectId, object, options ){

          var makeTabIdHash;
          var fromUserId;
          var storeTarget;

          // No comet required (from the option, or for the store's own request
          if( this.killComet || killCometOption ) return;

          // fromUserId taken from the session (if it exists) or set to null (it's an API call)
          fromUserId = ( this._req && this._req.session && this._req.session.userId ) || null;

          // If it's in a multi-home environment, use the specific multi-home filter
          // if( hotplate.config.get( 'hotCoreMultiHome.enabled' ) && object.workspaceId ) makeTabIdHash = exports.makeTabIdHashForMultihome;
          if( hotplate.config.get( 'hotCoreMultiHome.enabled' ) ) makeTabIdHash = hotCoreMultiHome.makeTabIdHashForMultihome;

          var message = { type: type, storeName: this.storeName, objectId: objectId, object: object };

          // If options.beforeId is set, make up a fake record with 'before' set as record with matching ID is idProperty
          // We cannot really send the whole record as we never fetch it fully
          if( options.beforeId ){
            if( options.beforeId === 'null' ){
              message.before = null;
            } else {
              message.before = {};
              message.before[ this.idProperty ] = options.beforeId;
            }
          }
          if( options.justReposition) message.justReposition = true;

          // Actually invoke the broadcast
          hotplate.hotEvents.emit('cometBroadcast', fromUserId, this._getTabId(), makeTabIdHash, message,  function(){}  );


          /*
            // What follows is the attempt to send a comet message for every store that uses the _collection_ modified by the
            // change. Unfortunately, sub-stores that change a subset of the data effectively cannot be done because
            // the comet message would be incomplete (it would only have some of the fields).


          hotCoreStoreRegistry.getAllStores( function( err, allStores ){


            allStores.collections[ self.collectionName ].forEach( function( s ){

              console.log("Setting up a message for ", s.storeObject.storeName );
              var message = { type: type, storeName: s.storeObject.storeName, objectId: objectId, object: object };
              console.log("The message is: ", message );

              // If options.beforeId is set, make up a fake record with 'before' set as record with matching ID is idProperty
              // We cannot really send the whole record as we never fetch it fully
              if( options.beforeId ){
                if( options.beforeId === 'null' ){
                  message.before = null;
                } else {
                  message.before = {};
                  message.before[ this.idProperty ] = options.beforeId;
                }
              }
              if( options.justReposition) message.justReposition = true;

              // Actually invoke the broadcast
              hotplate.hotEvents.emit('cometBroadcast', fromUserId, self._getTabId(), makeTabIdHash, message,  function(){}  );

            });

          } );
          */


        },
Пример #29
0
mongodb.MongoClient.connect( mongoUrl, {}, function( err, db ){

  // The connection is 100% necessary
  if( err ){
    hotplate.logger.error("Could not connect to the database. Aborting. Error: ", err );
    process.exit( 1 );
  }

  // Basic Hotplate setup. `routeUrlsPrefix` nees to be set here
  // since it might be used in modules at load-time
  hotplate.config.set( 'hotplate.routeUrlsPrefix', '/app' );

  // Require all of Hotplate's core modules
  // (You CAN be more selective if you like)
  require( 'hotplate/core_modules/hotCore' );

  // Require your app's main module(s) here
  var main = require( './main.js' );

  // More hotplate.config.set() commands can go here
  // (After loading modules, which might set some defaults for themselves)

  // Zap indexes by defailt. You will want to turn this off in production
  hotplate.config.set( 'hotCoreStore.zapIndexes', true );

  // Mandatory DB-specific stuff
  hotplate.config.set( 'hotplate.db', db );
  hotplate.config.set( 'hotplate.DbLayerMixin', DbLayerMixin );
  hotplate.config.set( 'hotplate.SchemaMixin', SchemaMixin );

  // Facebook strategy turned on
  hotplate.config.set('hotCoreAuth.strategies', {
    facebook: {
      clientID: 'YOUR_CLIENT_ID',
      clientSecret: 'YOUR_CLIENT_SECRET',
      fieldList: 'id,name,first_name,last_name,age_range,link,gender,locale,picture,timezone,updated_time,verified,email'
    },
    local: {
    },
  });

  // Express basic settings
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');

  // Various middleware. The usual suspects: static, favicon, logger,
  // bodyparser, cookieparser
  app.use('/', express.static(path.join(__dirname, 'public')));

  if( app.get( 'env' ) === 'development' ) app.use(logger('dev'));
  //app.use(favicon(__dirname + '/public/favicon.ico'));
  app.use(bodyParser.json());
  app.use(bodyParser.urlencoded({ extended: false }));
  app.use(cookieParser('woodchucks are nasty animals!!!'));
  app.use(cookieSession({ secret: 'woodchucks are nasty animals!!!' }));

  // Passport initialize
  app.use(passport.initialize());

  // Emit a `stores` signal, which will get each one of the Hotplate
  // modules to instance their stores.
  require('hotplate/core_modules/hotCoreStore').getAllStores( function( err, s ) {

    if( err ){
      console.error( "Error running the stores:", err );
      process.exit();
    }

    // Initialise JsonRestStores and SimpleDbLayer
    JsonRestStores.init();
    SimpleDbLayer.init();

    // Emit a setRoutes signal to Hotplate modules, which will set their routes
    // to the `app` object
    hotplate.hotEvents.emitCollect( 'setRoutes', app, function( err ) {
      if( err ){
        console.error( "Error setting the routes:", err );
        process.exit();
      }

      // Routes for password recovery
      app.post('/auth/recover', main.recoverPostRoute );
      app.get( '/auth/recoverPage/:token', main.recoverPageGetRoute );
      app.get( '/auth/recoverPageLanding/:token', main.recoverPageLandingGetRoute );
      app.post('/auth/resetPassword', main.resetPasswordPostRoute );

      // Error route
      app.use( require('hotplate/core_modules/hotCoreError').hotCoreErrorHandler );

      // You don't want to see this happen
      app.use( function( err, req, res, next){
        res.send("Oh dear, this should never happen!");
        next(err);
      });

      // Emit a run signal to Hotplate modules, which might set their
      // interval timers, etc.
      hotplate.hotEvents.emitCollect( 'run', function() {

        if( err ){
          console.error( "Error running the hook 'run':", err );
          process.exit();
        }

        // If TESTING is set, then this very module is being loaded
        // to run some tests. Since some of the things here are async,
        // this will tell the loading module when to run the tests
        if( process.env.TESTING ){
          process.emit( 'startTests', db );

        // Business as usual: create the server, listen to the port
        } else {
          var server = http.createServer( app );
          server.listen( app.get('port'), app.get('ipAddress'), function(){
            console.log("Express server listening on port " + app.get('port'));
          });

          // TODO: Remove, this is for debugging
          var server = http.createServer( app );
          server.listen( app.get('port'), '192.168.1.200', function(){
            console.log("AND Express server listening on port " + app.get('port'));
          });

        }

      });
    });
  });
});
Пример #30
0
"use strict";

/*!
 * Module dependencies.
 */

var dummy
  , hotplate = require('hotplate')
  , path = require('path')
  , hotCoreStoreRegistry = require( 'hotCoreStoreRegistry' )
;


hotplate.config.set( 'hotCoreStoreExposer.storesUrlsPrefix', "/stores" );

// Run onlineAll for each store with a publicUrl attribute

hotplate.hotEvents.on( 'setRoutes', hotplate.cachable( function( app, done ){

  hotCoreStoreRegistry.getAllStores( function( err, allStores ){  
    
    Object.keys( allStores ).forEach( function( storeName ){
      
      var store = allStores[ storeName ];

      // The store has a public URL: add it to the list of stores to expose
      // Note that I pass the modified URL to setAllRoutes
      if( store.hotExpose ){
        var url = path.join( hotplate.config.get( 'hotCoreStoreExposer.storesUrlsPrefix' ), store.publicURL );
        store.setAllRoutes( app, url );
      }