<commit_before>var passport = require('passport')
  , path     = require('path')
  , url      = require('url');

/**
 * Passport Service
 *
 * A painless Passport.js service for your Sails app that is guaranteed to
 * Rock Your Socks™. It takes all the hassle out of setting up Passport.js by
 * encapsulating all the boring stuff in two functions:
 *
 *   passport.endpoint()
 *   passport.callback()
 *
 * The former sets up an endpoint (/auth/:provider) for redirecting a user to a
 * third-party provider for authentication, while the latter sets up a callback
 * endpoint (/auth/:provider/callback) for receiving the response from the
 * third-party provider. All you have to do is define in the configuration which
 * third-party providers you'd like to support. It's that easy!
 *
 * Behind the scenes, the service stores all the data it needs within "Pass-
 * ports". These contain all the information required to associate a local user
 * with a profile from a third-party provider. This even holds true for the good
 * ol' password authentication scheme – the Authentication Service takes care of
 * encrypting passwords and storing them in Passports, allowing you to keep your
 * User model free of bloat.
 */

// Load authentication protocols
passport.protocols = require('./protocols');

/**
 * Connect a third-party profile to a local user
 *
 * This is where most of the magic happens when a user is authenticating with a
 * third-party provider. What it does, is the following:
 *
 *   1. Given a provider and an identifier, find a mathcing Passport.
 *   2. From here, the logic branches into two paths.
 *
 *     - A user is not currently logged in:
 *       1. If a Passport wassn't found, create a new user as well as a new
 *          Passport that will be assigned to the user.
 *       2. If a Passport was found, get the user associated with the passport.
 *
 *     - A user is currently logged in:
 *       1. If a Passport wasn't found, create a new Passport and associate it
 *          with the already logged in user (ie. "Connect")
 *       2. If a Passport was found, nothing needs to happen.
 *
 * As you can see, this function handles both "authentication" and "authori-
 * zation" at the same time. This is due to the fact that we pass in
 * `passReqToCallback: true` when loading the strategies, allowing us to look
 * for an existing session in the request and taking action based on that.
 *
 * For more information on auth(entication|rization) in Passport.js, check out:
 * http://passportjs.org/guide/authenticate/
 * http://passportjs.org/guide/authorize/
 *
 * @param {Object}   req
 * @param {Object}   query
 * @param {Object}   profile
 * @param {Function} next
 */
passport.connect = function (req, query, profile, next) {
  var strategies = sails.config.passport
    , config     = strategies[profile.provider]
    , user       = {};

  // Set the authentication provider.
  query.provider = req.param('provider');

  // If the profile object contains a list of emails, grab the first one and
  // add it to the user.
  if (profile.hasOwnProperty('emails')) {
    user.email = profile.emails[0].value;
  }
  // If the profile object contains a username, add it to the user.
  if (profile.hasOwnProperty('username')) {
    user.username = profile.username;
  }

  // If neither an email or a username was available in the profile, we don't
  // have a way of identifying the user in the future. Throw an error and let
  // whoever's next in the line take care of it.
  if (!Object.keys(user).length) {
    return next(new Error('Neither a username or email was available', null));
  }

  Passport.findOne({
    provider   : profile.provider
  , identifier : query.identifier
  })
  .populate('user')
  .done(function (err, passport) {
    if (err) return next(err);

    if (!req.user) {
      // Scenario: A new user is attempting to sign up using a third-party
      //           authentication provider.
      // Action:   Create a new user and assign them a passport.
      if (!passport) {
        User.create(user).done(function (err, user) {
          if (err) return next(err);

          query.user = user.id;

          Passport.create(query).done(function (err, passport) {
            // If a passport wasn't created, bail out
            if (err) return next(err);

            next(err, user);
          });
        });
      }
      // Scenario: An existing user is trying to log in using an already
      //           connected passport.
      // Action:   Get the user associated with the passport.
      else {
        next(null, passport.user);
      }
    } else {
      // Scenario: A user is currently logged in and trying to connect a new
      //           passport.
      // Action:   Create and assign a new passport to the user.
      if (!passport) {
        query.user = req.user.id;

        Passport.create(query).done(function (err, passport) {
          // If a passport wasn't created, bail out
          if (err) return next(err);

          next(err, req.user);
        });
      }
      // Scenario: The user is a nutjob or spammed the back-button.
      // Action:   Simply pass along the already established session.
      else {
        next(null, req.user);
      }
    }
  });
};

/**
 * Create an authentication endpoint
 *
 * For more information on authentication in Passport.js, check out:
 * http://passportjs.org/guide/authenticate/
 *
 * @param  {Object} req
 * @param  {Object} res
 */
passport.endpoint = function (req, res) {
  var strategies = sails.config.passport
    , provider   = req.param('provider')
    , options    = {};

  // If a provider doesn't exist for this endpoint, send the user back to the
  // login page
  if (!strategies.hasOwnProperty(provider)) {
    return res.redirect('/login');
  }

  // Attach scope if it has been set in the config
  if (strategies[provider].hasOwnProperty('scope')) {
    options.scope = strategies[provider].scope;
  }

  // Load authentication strategies
  this.loadStrategies(req);

  // Redirect the user to the provider for authentication. When complete,
  // the provider will redirect the user back to the application at
  //     /auth/:provider/callback
  this.authenticate(provider, options)(req, res, req.next);
};

/**
 * Create an authentication callback endpoint
 *
 * For more information on authentication in Passport.js, check out:
 * http://passportjs.org/guide/authenticate/
 *
 * @param {Object}   req
 * @param {Object}   res
 * @param {Function} next
 */
passport.callback = function (req, res, next) {
  var provider = req.param('provider', 'local')
    , action   = req.param('action');

  // Passport.js wasn't really built for local user registration, but it's nice
  // having it tied into everything else.
  if (provider === 'local' && action !== undefined) {
    if (action === 'register' && !req.user) {
      this.protocols.local.register(req, res, next);
    }
    else if (action === 'connect' && req.user) {
      this.protocols.local.connect(req, res, next);
    }
    else {
      next(new Error('Invalid action'));
    }
  } else {
    // Load authentication strategies
    this.loadStrategies(req);

    // The provider will redirect the user to this URL after approval. Finish
    // the authentication process by attempting to obtain an access token. If
    // access was granted, the user will be logged in. Otherwise, authentication
    // has failed.
    this.authenticate(provider, next)(req, res, req.next);
  }
};

/**
 * Load all strategies defined in the Passport configuration
 *
 * For example, we could add this to our config to use the GitHub strategy
 * with permission to access a users email address (even if it's marked as
 * private) as well as permission to add and update a user's Gists:
 *
    github: {
      name: 'GitHub',
      protocol: 'oauth2',
      scope: [ 'user', 'gist' ]
      options: {
        clientID: 'CLIENT_ID',
        clientSecret: 'CLIENT_SECRET'
      }
    }
 *
 * For more information on the providers supported by Passport.js, check out:
 * http://passportjs.org/guide/providers/
 *
 * @param {Object} req
 */
passport.loadStrategies = function (req) {
  var self       = this
    , strategies = sails.config.passport;

  Object.keys(strategies).forEach(function (key) {
    var Strategy = require('passport-' + key).Strategy
      , options  = { passReqToCallback: true };

    if (key === 'local') {
      // Since we need to allow users to login using both usernames as well as
      // emails, we'll set the username field to something more generic.
      _.extend(options, { usernameField: 'identifier' });

      // Only load the local strategy if it's enabled in the config
      if (strategies[key]) {
        self.use(new Strategy(options, self.protocols.local.login));
      }
    } else {
      var protocol   = strategies[key].protocol
        , callback   = path.join('auth', key, 'callback');

      switch (protocol) {
        case 'oauth':
        case 'oauth2':
          options.callbackURL = url.resolve(req.baseUrl, callback);
          break;

        case 'openid':
          options.returnURL = url.resolve(req.baseUrl, callback);
          options.realm     = req.baseUrl;
          options.profile   = true;
          break;
      }

      // Merge the default options with any options defined in the config. All
      // defaults can be overriden, but I don't see a reason why you'd want to
      // do that.
      _.extend(options, strategies[key].options);

      self.use(new Strategy(options, self.protocols[protocol]));
    }
  });
};

passport.serializeUser(function (user, next) {
  next(null, user.id);
});

passport.deserializeUser(function (id, next) {
  User.findOne(id).done(next);
});

module.exports = passport;
<commit_msg>Fixes #17: Update Passport tokens between sessions<commit_after>var passport = require('passport')
  , path     = require('path')
  , url      = require('url');

/**
 * Passport Service
 *
 * A painless Passport.js service for your Sails app that is guaranteed to
 * Rock Your Socks™. It takes all the hassle out of setting up Passport.js by
 * encapsulating all the boring stuff in two functions:
 *
 *   passport.endpoint()
 *   passport.callback()
 *
 * The former sets up an endpoint (/auth/:provider) for redirecting a user to a
 * third-party provider for authentication, while the latter sets up a callback
 * endpoint (/auth/:provider/callback) for receiving the response from the
 * third-party provider. All you have to do is define in the configuration which
 * third-party providers you'd like to support. It's that easy!
 *
 * Behind the scenes, the service stores all the data it needs within "Pass-
 * ports". These contain all the information required to associate a local user
 * with a profile from a third-party provider. This even holds true for the good
 * ol' password authentication scheme – the Authentication Service takes care of
 * encrypting passwords and storing them in Passports, allowing you to keep your
 * User model free of bloat.
 */

// Load authentication protocols
passport.protocols = require('./protocols');

/**
 * Connect a third-party profile to a local user
 *
 * This is where most of the magic happens when a user is authenticating with a
 * third-party provider. What it does, is the following:
 *
 *   1. Given a provider and an identifier, find a mathcing Passport.
 *   2. From here, the logic branches into two paths.
 *
 *     - A user is not currently logged in:
 *       1. If a Passport wassn't found, create a new user as well as a new
 *          Passport that will be assigned to the user.
 *       2. If a Passport was found, get the user associated with the passport.
 *
 *     - A user is currently logged in:
 *       1. If a Passport wasn't found, create a new Passport and associate it
 *          with the already logged in user (ie. "Connect")
 *       2. If a Passport was found, nothing needs to happen.
 *
 * As you can see, this function handles both "authentication" and "authori-
 * zation" at the same time. This is due to the fact that we pass in
 * `passReqToCallback: true` when loading the strategies, allowing us to look
 * for an existing session in the request and taking action based on that.
 *
 * For more information on auth(entication|rization) in Passport.js, check out:
 * http://passportjs.org/guide/authenticate/
 * http://passportjs.org/guide/authorize/
 *
 * @param {Object}   req
 * @param {Object}   query
 * @param {Object}   profile
 * @param {Function} next
 */
passport.connect = function (req, query, profile, next) {
  var strategies = sails.config.passport
    , config     = strategies[profile.provider]
    , user       = {};

  // Set the authentication provider.
  query.provider = req.param('provider');

  // If the profile object contains a list of emails, grab the first one and
  // add it to the user.
  if (profile.hasOwnProperty('emails')) {
    user.email = profile.emails[0].value;
  }
  // If the profile object contains a username, add it to the user.
  if (profile.hasOwnProperty('username')) {
    user.username = profile.username;
  }

  // If neither an email or a username was available in the profile, we don't
  // have a way of identifying the user in the future. Throw an error and let
  // whoever's next in the line take care of it.
  if (!Object.keys(user).length) {
    return next(new Error('Neither a username or email was available', null));
  }

  Passport.findOne({
    provider   : profile.provider
  , identifier : query.identifier
  })
  .populate('user')
  .done(function (err, passport) {
    if (err) return next(err);

    if (!req.user) {
      // Scenario: A new user is attempting to sign up using a third-party
      //           authentication provider.
      // Action:   Create a new user and assign them a passport.
      if (!passport) {
        User.create(user).done(function (err, user) {
          if (err) return next(err);

          query.user = user.id;

          Passport.create(query).done(function (err, passport) {
            // If a passport wasn't created, bail out
            if (err) return next(err);

            next(err, user);
          });
        });
      }
      // Scenario: An existing user is trying to log in using an already
      //           connected passport.
      // Action:   Get the user associated with the passport.
      else {
        // If the tokens have changed since the last session, update them
        if (query.hasOwnProperty('tokens') && query.tokens !== passport.tokens) {
          passport.tokens = query.tokens;
        }

        user = passport.user;

        // Save any updates to the Passport before moving on
        passport.save(function (err, passport) {
          next(err, user);
        });
      }
    } else {
      // Scenario: A user is currently logged in and trying to connect a new
      //           passport.
      // Action:   Create and assign a new passport to the user.
      if (!passport) {
        query.user = req.user.id;

        Passport.create(query).done(function (err, passport) {
          // If a passport wasn't created, bail out
          if (err) return next(err);

          next(err, req.user);
        });
      }
      // Scenario: The user is a nutjob or spammed the back-button.
      // Action:   Simply pass along the already established session.
      else {
        next(null, req.user);
      }
    }
  });
};

/**
 * Create an authentication endpoint
 *
 * For more information on authentication in Passport.js, check out:
 * http://passportjs.org/guide/authenticate/
 *
 * @param  {Object} req
 * @param  {Object} res
 */
passport.endpoint = function (req, res) {
  var strategies = sails.config.passport
    , provider   = req.param('provider')
    , options    = {};

  // If a provider doesn't exist for this endpoint, send the user back to the
  // login page
  if (!strategies.hasOwnProperty(provider)) {
    return res.redirect('/login');
  }

  // Attach scope if it has been set in the config
  if (strategies[provider].hasOwnProperty('scope')) {
    options.scope = strategies[provider].scope;
  }

  // Load authentication strategies
  this.loadStrategies(req);

  // Redirect the user to the provider for authentication. When complete,
  // the provider will redirect the user back to the application at
  //     /auth/:provider/callback
  this.authenticate(provider, options)(req, res, req.next);
};

/**
 * Create an authentication callback endpoint
 *
 * For more information on authentication in Passport.js, check out:
 * http://passportjs.org/guide/authenticate/
 *
 * @param {Object}   req
 * @param {Object}   res
 * @param {Function} next
 */
passport.callback = function (req, res, next) {
  var provider = req.param('provider', 'local')
    , action   = req.param('action');

  // Passport.js wasn't really built for local user registration, but it's nice
  // having it tied into everything else.
  if (provider === 'local' && action !== undefined) {
    if (action === 'register' && !req.user) {
      this.protocols.local.register(req, res, next);
    }
    else if (action === 'connect' && req.user) {
      this.protocols.local.connect(req, res, next);
    }
    else {
      next(new Error('Invalid action'));
    }
  } else {
    // Load authentication strategies
    this.loadStrategies(req);

    // The provider will redirect the user to this URL after approval. Finish
    // the authentication process by attempting to obtain an access token. If
    // access was granted, the user will be logged in. Otherwise, authentication
    // has failed.
    this.authenticate(provider, next)(req, res, req.next);
  }
};

/**
 * Load all strategies defined in the Passport configuration
 *
 * For example, we could add this to our config to use the GitHub strategy
 * with permission to access a users email address (even if it's marked as
 * private) as well as permission to add and update a user's Gists:
 *
    github: {
      name: 'GitHub',
      protocol: 'oauth2',
      scope: [ 'user', 'gist' ]
      options: {
        clientID: 'CLIENT_ID',
        clientSecret: 'CLIENT_SECRET'
      }
    }
 *
 * For more information on the providers supported by Passport.js, check out:
 * http://passportjs.org/guide/providers/
 *
 * @param {Object} req
 */
passport.loadStrategies = function (req) {
  var self       = this
    , strategies = sails.config.passport;

  Object.keys(strategies).forEach(function (key) {
    var Strategy = require('passport-' + key).Strategy
      , options  = { passReqToCallback: true };

    if (key === 'local') {
      // Since we need to allow users to login using both usernames as well as
      // emails, we'll set the username field to something more generic.
      _.extend(options, { usernameField: 'identifier' });

      // Only load the local strategy if it's enabled in the config
      if (strategies[key]) {
        self.use(new Strategy(options, self.protocols.local.login));
      }
    } else {
      var protocol   = strategies[key].protocol
        , callback   = path.join('auth', key, 'callback');

      switch (protocol) {
        case 'oauth':
        case 'oauth2':
          options.callbackURL = url.resolve(req.baseUrl, callback);
          break;

        case 'openid':
          options.returnURL = url.resolve(req.baseUrl, callback);
          options.realm     = req.baseUrl;
          options.profile   = true;
          break;
      }

      // Merge the default options with any options defined in the config. All
      // defaults can be overriden, but I don't see a reason why you'd want to
      // do that.
      _.extend(options, strategies[key].options);

      self.use(new Strategy(options, self.protocols[protocol]));
    }
  });
};

passport.serializeUser(function (user, next) {
  next(null, user.id);
});

passport.deserializeUser(function (id, next) {
  User.findOne(id).done(next);
});

module.exports = passport;
<|endoftext|>


<commit_before>// ==UserScript==
// @name         Ads DOM Remover
// @namespace    sagiegurari
// @version      0.84
// @author       Sagie Gur-Ari
// @description  Removes Ad Containers from DOM (doesn't replace adblocker extension, but blocks dynamic content which the adblocker fails to block by removing whole sections from the HTML DOM.)
// @homepage     https://github.com/sagiegurari/userscripts-ads-dom-remover
// @supportURL   https://github.com/sagiegurari/userscripts-ads-dom-remover/issues
// @match        http://www.ynet.co.il/home/*
// @match        http://www.ynet.co.il/articles/*
// @match        http://www.mynet.co.il/articles/*
// @match        http://www.calcalist.co.il/*
// @match        http://www.globes.co.il/*
// @match        https://sourceforge.net/projects/*/download*
// @match        http://subscenter.cinemast.com/*
// @match        http://www.subscenter.co/*
// @match        https://*.wikipedia.org/*
// @require      https://code.jquery.com/jquery-2.2.2.min.js
// @require      https://greasyfork.org/scripts/18490-ads-dom-remover-runner/code/Ads%20DOM%20Remover%20Runner.js?version=123541
// @grant        none
// @license      MIT License
// ==/UserScript==

(function run($, runner) {
    'use strict';

    var selectorDefinitions = {
        ynet: [
            '#colorbox',
            '#cboxOverlay',
            '#ads.premium',
            '#articleLayoutrightsidtable',
            'img[src*="dynamicyield"]',
            'div.MSCmainContent',
            '[id*="arketingCarouse"]',
            '[id*="arketingRecommended"]',
            '.mainVerticalArticleSharingLinks',
            '.OUTBRAIN',
            '.topBannerWrap',
            '.block.B3 .B3.ghcite.dyother.dyMonitor div',
            '.bigdealhomepage',
            '#ww6s_Main',
            '.buyandsavedy',
            '.area.footer.ghcite',
            '.hdr_set_homepage',
            '#c1_Hor',
            '#c2_Hor',
            '#c3_Hor',
            '#c4_Hor',
            '#c5_Hor',
            '#c6_Hor',
            '.homepagevideo-x6',
            '.buyandsave',
            '.general-image',
            '.PhotoArticlesTalkbacks',
            '[name="ExternalWebpageIframe"]',
            '#PROCOIL_SearchForm',
            '#magazines1024',
            '[id^="promo_"]',
            '.main_search_radio',
            'tr td [id^="ads."]',
            {
                selector: '.homepagelitevideo',
                fineTuneSelector: function ($element) {
                    return $element.parent().parent();
                }
            },
            {
                selector: 'iframe',
                filter: function ($element) {
                    return !$element.parent().hasClass('news_ticker_iframe');
                }
            },
            {
                selector: 'div.B2b.block div',
                pre: function ($element) {
                    $element.parent().css({
                        height: '1px'
                    });
                }
            }
        ],
        globes: [
            '#chromeWindow',
            {
                selector: 'iframe',
                filter: function ($element) {
                    var id = $element.attr('id');
                    var src = $element.attr('src') || '';

                    return (id !== 'GlobalFinanceData_home') && (src.indexOf('/news/') !== -1);
                }
            }
        ],
        sourceforge: [
            '#content-for-adblock'
        ],
        subscenter: [
            '.weekBottom',
            '.reviewsWindow',
            '#banner_cinemast',
            '.bottomMenu',
            'footer',
            '#paypal',
            '#aboveSite',
            {
                selector: '#subtitles_list a[href~="openab"]',
                fineTuneSelector: function ($element) {
                    return $element.parent();
                }
            }
        ],
        wikipedia: [
            '#frbanner',
            '.frbanner'
        ]
    };

    [
        '#dcPremiumRightImg',
        '.boulevard',
        '#multiarticles-9',
        '#multiarticles-12',
        '#multiarticles-13',
        '#multiarticles-14',
        '#multiarticles-15',
        '#multiarticles-16'
    ].forEach(function addSelector(selector) {
        selectorDefinitions.ynet.push({
            selector: selector,
            fineTuneSelector: function ($element) {
                return $element.parent();
            }
        });
    });

    Object.keys(selectorDefinitions).forEach(function (id) {
        selectorDefinitions[id] = {
            id: id,
            selectors: selectorDefinitions[id]
        };
    });

    runner($, {
        getSelectors: function (hostName) {
            var selectors;
            if (hostName.indexOf('globes') !== -1) {
                selectors = selectorDefinitions.globes;
            } else if (hostName.indexOf('sourceforge.net') !== -1) {
                selectors = selectorDefinitions.sourceforge;
            } else if (hostName.indexOf('subscenter') !== -1) {
                selectors = selectorDefinitions.subscenter;
            } else if (hostName.indexOf('wikipedia.org') !== -1) {
                selectors = selectorDefinitions.wikipedia;
            } else { //ynet/calcalist
                selectors = selectorDefinitions.ynet;
            }

            return selectors;
        }
    });
}(window.jQuery.noConflict(true), window.adrRunner));
<commit_msg>more selectors<commit_after>// ==UserScript==
// @name         Ads DOM Remover
// @namespace    sagiegurari
// @version      0.85
// @author       Sagie Gur-Ari
// @description  Removes Ad Containers from DOM (doesn't replace adblocker extension, but blocks dynamic content which the adblocker fails to block by removing whole sections from the HTML DOM.)
// @homepage     https://github.com/sagiegurari/userscripts-ads-dom-remover
// @supportURL   https://github.com/sagiegurari/userscripts-ads-dom-remover/issues
// @match        http://www.ynet.co.il/home/*
// @match        http://www.ynet.co.il/articles/*
// @match        http://www.mynet.co.il/articles/*
// @match        http://www.calcalist.co.il/*
// @match        http://www.globes.co.il/*
// @match        https://sourceforge.net/projects/*/download*
// @match        http://subscenter.cinemast.com/*
// @match        http://www.subscenter.co/*
// @match        https://*.wikipedia.org/*
// @require      https://code.jquery.com/jquery-2.2.2.min.js
// @require      https://greasyfork.org/scripts/18490-ads-dom-remover-runner/code/Ads%20DOM%20Remover%20Runner.js?version=123541
// @grant        none
// @license      MIT License
// ==/UserScript==

(function run($, runner) {
    'use strict';

    var selectorDefinitions = {
        ynet: [
            '#colorbox',
            '#cboxOverlay',
            '#ads.premium',
            '#articleLayoutrightsidtable',
            'img[src*="dynamicyield"]',
            'div.MSCmainContent',
            '[id*="arketingCarouse"]',
            '[id*="arketingRecommended"]',
            '.mainVerticalArticleSharingLinks',
            '.OUTBRAIN',
            '.topBannerWrap',
            '.block.B3 .B3.ghcite.dyother.dyMonitor div',
            '.bigdealhomepage',
            '#ww6s_Main',
            '.buyandsavedy',
            '.area.footer.ghcite',
            '.hdr_set_homepage',
            '#c1_Hor',
            '#c2_Hor',
            '#c3_Hor',
            '#c4_Hor',
            '#c5_Hor',
            '#c6_Hor',
            '.homepagevideo-x6',
            '.buyandsave',
            '.general-image',
            '.PhotoArticlesTalkbacks',
            '[name="ExternalWebpageIframe"]',
            '#PROCOIL_SearchForm',
            '#magazines1024',
            '[id^="promo_"]',
            '.main_search_radio',
            'tr td [id^="ads."]',
            {
                selector: '.homepagelitevideo',
                fineTuneSelector: function ($element) {
                    return $element.parent().parent();
                }
            },
            {
                selector: 'iframe',
                filter: function ($element) {
                    return !$element.parent().hasClass('news_ticker_iframe');
                }
            },
            {
                selector: 'div.B2b.block div',
                pre: function ($element) {
                    $element.parent().css({
                        height: '1px'
                    });
                }
            }
        ],
        globes: [
            '#chromeWindow',
            {
                selector: 'iframe',
                filter: function ($element) {
                    var id = $element.attr('id');
                    var src = $element.attr('src') || '';

                    return (id !== 'GlobalFinanceData_home') && (src.indexOf('/news/') !== -1);
                }
            }
        ],
        sourceforge: [
            '#content-for-adblock'
        ],
        subscenter: [
            '.weekBottom',
            '.reviewsWindow',
            '#banner_cinemast',
            '.bottomMenu',
            'footer',
            '#paypal',
            '#aboveSite',
            {
                selector: '#subtitles_list a[href="/he/contactus/"]',
                fineTuneSelector: function ($element) {
                    return $element.parent();
                }
            }
        ],
        wikipedia: [
            '#frbanner',
            '.frbanner'
        ]
    };

    [
        '#dcPremiumRightImg',
        '.boulevard',
        '#multiarticles-9',
        '#multiarticles-12',
        '#multiarticles-13',
        '#multiarticles-14',
        '#multiarticles-15',
        '#multiarticles-16'
    ].forEach(function addSelector(selector) {
        selectorDefinitions.ynet.push({
            selector: selector,
            fineTuneSelector: function ($element) {
                return $element.parent();
            }
        });
    });

    Object.keys(selectorDefinitions).forEach(function (id) {
        selectorDefinitions[id] = {
            id: id,
            selectors: selectorDefinitions[id]
        };
    });

    runner($, {
        getSelectors: function (hostName) {
            var selectors;
            if (hostName.indexOf('globes') !== -1) {
                selectors = selectorDefinitions.globes;
            } else if (hostName.indexOf('sourceforge.net') !== -1) {
                selectors = selectorDefinitions.sourceforge;
            } else if (hostName.indexOf('subscenter') !== -1) {
                selectors = selectorDefinitions.subscenter;
            } else if (hostName.indexOf('wikipedia.org') !== -1) {
                selectors = selectorDefinitions.wikipedia;
            } else { //ynet/calcalist
                selectors = selectorDefinitions.ynet;
            }

            return selectors;
        }
    });
}(window.jQuery.noConflict(true), window.adrRunner));
<|endoftext|>


<commit_before>import React from 'react';
import ReactDOM from 'react-dom';
import _ from 'lodash';
import Webiny from 'webiny';
import styles from './styles.css';

// TODO: https://www.npmjs.com/package/react-google-maps

class GoogleMap extends Webiny.Ui.FormComponent {

    constructor(props) {
        super(props);

        this.map = null;
        this.marker = null;
        this.geoCoder = null;
        this.loading = null;

        this.bindMethods('positionMarker,setupMap,search');
    }

    componentDidMount() {
        if (!window.google) {
            return Webiny.Page.loadScript('https://maps.googleapis.com/maps/api/js?key=' + this.props.apiKey).then(() => {
                this.setupMap();
            });
        }

        this.setupMap();
    }

    shouldComponentUpdate(newProps) {
        if (!newProps.value) {
            return false;
        }

        return !_.isEqual(this.props.value, newProps.value);
    }

    componentDidUpdate() {
        if (!this.map) {
            return;
        }

        this.positionMarker();
    }

    setupMap() {
        const lat = _.get(this.props, 'value.lat', this.props.center.lat);
        const lng = _.get(this.props, 'value.lng', this.props.center.lng);

        this.map = new google.maps.Map(ReactDOM.findDOMNode(this).querySelector('[data-role="map"]'), {
            center: new google.maps.LatLng(parseFloat(lat), parseFloat(lng)),
            zoom: this.props.zoom,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        });

        this.marker = new google.maps.Marker({
            map: this.map,
            draggable: true
        });

        if (!this.props.readOnly) {
            google.maps.event.addListener(this.marker, 'dragend', () => {
                this.props.onChange({
                    lat: this.marker.getPosition().lat(),
                    lng: this.marker.getPosition().lng()
                });
            });
        }

        this.positionMarker();
    }

    positionMarker() {
        const lat = _.get(this.props, 'value.lat');
        const lng = _.get(this.props, 'value.lng');

        if (lat && lng) {
            const latLng = new google.maps.LatLng(parseFloat(lat), parseFloat(lng));
            this.map.panTo(latLng);
            this.marker.setMap(this.map);
            this.marker.setPosition(latLng);
        }
    }

    search(query) {
        if (!this.geoCoder) {
            this.geoCoder = new google.maps.Geocoder();
        }

        this.geoCoder.geocode({address: query}, results => {
            if (!_.isEmpty(results)) {
                const location = _.get(results[0], 'geometry.location');
                this.props.onChange({
                    lat: location.lat(),
                    lng: location.lng()
                });
            }
        });
    }
}

GoogleMap.defaultProps = {
    apiKey: null,
    zoom: 4,
    center: {
        lat: 0,
        lng: 0
    },
    readOnly: false,
    style: null,
    value: null,
    onChange: _.noop,
    renderer() {
        const {styles} = this.props;
        return (

{this.props.children}

        );
    }
};

export default Webiny.createComponent(GoogleMap, {styles, api: ['search']});<commit_msg>Exposed missing api method.<commit_after>import React from 'react';
import ReactDOM from 'react-dom';
import _ from 'lodash';
import Webiny from 'webiny';
import styles from './styles.css';

// TODO: https://www.npmjs.com/package/react-google-maps

class GoogleMap extends Webiny.Ui.FormComponent {

    constructor(props) {
        super(props);

        this.map = null;
        this.marker = null;
        this.geoCoder = null;
        this.loading = null;

        this.bindMethods('positionMarker,setupMap,search');
    }

    componentDidMount() {
        if (!window.google) {
            return Webiny.Page.loadScript('https://maps.googleapis.com/maps/api/js?key=' + this.props.apiKey).then(() => {
                this.setupMap();
            });
        }

        this.setupMap();
    }

    shouldComponentUpdate(newProps) {
        if (!newProps.value) {
            return false;
        }

        return !_.isEqual(this.props.value, newProps.value);
    }

    componentDidUpdate() {
        if (!this.map) {
            return;
        }

        this.positionMarker();
    }

    setupMap() {
        const lat = _.get(this.props, 'value.lat', this.props.center.lat);
        const lng = _.get(this.props, 'value.lng', this.props.center.lng);

        this.map = new google.maps.Map(ReactDOM.findDOMNode(this).querySelector('[data-role="map"]'), {
            center: new google.maps.LatLng(parseFloat(lat), parseFloat(lng)),
            zoom: this.props.zoom,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        });

        this.marker = new google.maps.Marker({
            map: this.map,
            draggable: true
        });

        if (!this.props.readOnly) {
            google.maps.event.addListener(this.marker, 'dragend', () => {
                this.props.onChange({
                    lat: this.marker.getPosition().lat(),
                    lng: this.marker.getPosition().lng()
                });
            });
        }

        this.positionMarker();
    }

    positionMarker() {
        const lat = _.get(this.props, 'value.lat');
        const lng = _.get(this.props, 'value.lng');

        if (lat && lng) {
            const latLng = new google.maps.LatLng(parseFloat(lat), parseFloat(lng));
            this.map.panTo(latLng);
            this.marker.setMap(this.map);
            this.marker.setPosition(latLng);
        }
    }

    search(query) {
        if (!this.geoCoder) {
            this.geoCoder = new google.maps.Geocoder();
        }

        this.geoCoder.geocode({address: query}, results => {
            if (!_.isEmpty(results)) {
                const location = _.get(results[0], 'geometry.location');
                this.props.onChange({
                    lat: location.lat(),
                    lng: location.lng()
                });
            }
        });
    }
}

GoogleMap.defaultProps = {
    apiKey: null,
    zoom: 4,
    center: {
        lat: 0,
        lng: 0
    },
    readOnly: false,
    style: null,
    value: null,
    onChange: _.noop,
    renderer() {
        const {styles} = this.props;
        return (

{this.props.children}

        );
    }
};

export default Webiny.createComponent(GoogleMap, {styles, api: ['search', 'positionMarker']});<|endoftext|>


<commit_before>define( ["backbone", "backbone.marionette", "communicator", "medium.editor", "config", "jquery", "erfgeoviewer.common",
    "tpl!template/detail.html"],
  function( Backbone, Marionette, Communicator, MediumEditor, Config, $, App,
            Template ) {

    return Marionette.ItemView.extend( {

      template: Template,
      layout: null,
      dom: {},

      events: {
        "click .change-style": function(e) {
          e.preventDefault();
        }
      },

      initialize: function( o ) {
        this.model = o.model;
        Communicator.mediator.on( "map:tile-layer-clicked", this.hideFlyout, this);
      },

      onShow: function() {

        var singleLiners = [],
            multiLiners = [],
            self = this,
            timeout;

        // Change configuration based on whether properties found in DOM.
        _.each( $(".editable", this.$el).get(), function( e ) {
          if ( $( e ).data( 'multiline' ) ) {
            multiLiners.push(e);
          } else {
            singleLiners.push(e);
          }
        } );

        // Move the controls region just after the title, no matter where it has been placed.
        $controls = $('#detail-controls');
        $('.row.title', this.$el).after( $controls );
        $controls.addClass('visible');

        if (this.singleLineEditor) this.singleLineEditor.destroy();
        if (this.multiLineEditor) this.multiLineEditor.destroy();

        if (App.mode == "mapmaker") {

          this.singleLineEditor = new MediumEditor(singleLiners, {
            buttons: ['bold', 'italic', 'underline', 'anchor'],
            disableReturn: true,
            imageDragging: false
          });

          this.multiLineEditor = new MediumEditor(multiLiners, {
            buttons: ['bold', 'italic', 'underline', 'anchor'],
            disableReturn: false
          });

          var f = function (event, editable) {
            clearTimeout(timeout);
            timeout = setTimeout(function() {
              var field = $(editable).attr('id').substr(5);
              self.model.set(field, $(editable).html());
            }, 1000);
          };
          this.singleLineEditor.subscribe( 'editableInput', f );
          this.multiLineEditor.subscribe( 'editableInput', f );

        }

      },

      serializeModel: function(model) {
        if (App.mode == 'reader' || model.get('externalUrl')) {
          return _.extend({
            fields: Config.fields
          }, model.toJSON.apply(model, _.rest(arguments)));
        }
        else {
          return _.extend({
            fields: Config.fields
          }, model.toJSON.apply(model, _.rest(arguments)), {
            externalUrl: 'url'
          });
        }
      }

    } );

  } );
<commit_msg>fixed exception when there is no multiline editor for an item. refs #9068<commit_after>define( ["backbone", "backbone.marionette", "communicator", "medium.editor", "config", "jquery", "erfgeoviewer.common",
    "tpl!template/detail.html"],
  function( Backbone, Marionette, Communicator, MediumEditor, Config, $, App,
            Template ) {

    return Marionette.ItemView.extend( {

      template: Template,
      layout: null,
      dom: {},

      events: {
        "click .change-style": function(e) {
          e.preventDefault();
        }
      },

      initialize: function( o ) {
        this.model = o.model;
        Communicator.mediator.on( "map:tile-layer-clicked", this.hideFlyout, this);
      },

      onShow: function() {

        var singleLiners = [],
            multiLiners = [],
            self = this,
            timeout;

        // Change configuration based on whether properties found in DOM.
        _.each( $(".editable", this.$el).get(), function( e ) {
          if ( $( e ).data( 'multiline' ) ) {
            multiLiners.push(e);
          } else {
            singleLiners.push(e);
          }
        } );

        // Move the controls region just after the title, no matter where it has been placed.
        $controls = $('#detail-controls');
        $('.row.title', this.$el).after( $controls );
        $controls.addClass('visible');

        if (this.singleLineEditor) this.singleLineEditor.destroy();
        if (this.multiLineEditor) this.multiLineEditor.destroy();

        if (App.mode == "mapmaker") {

          this.singleLineEditor = new MediumEditor(singleLiners, {
            buttons: ['bold', 'italic', 'underline', 'anchor'],
            disableReturn: true,
            imageDragging: false
          });

          this.multiLineEditor = new MediumEditor(multiLiners, {
            buttons: ['bold', 'italic', 'underline', 'anchor'],
            disableReturn: false
          });

          var f = function (event, editable) {
            clearTimeout(timeout);
            timeout = setTimeout(function() {
              var field = $(editable).attr('id').substr(5);
              self.model.set(field, $(editable).html());
            }, 1000);
          };

          if (singleLiners.length > 0) {
            this.singleLineEditor.subscribe( 'editableInput', f );
          }
          if (multiLiners.length > 0) {
            this.multiLineEditor.subscribe( 'editableInput', f );
          }

        }

      },

      serializeModel: function(model) {
        if (App.mode == 'reader' || model.get('externalUrl')) {
          return _.extend({
            fields: Config.fields
          }, model.toJSON.apply(model, _.rest(arguments)));
        }
        else {
          return _.extend({
            fields: Config.fields
          }, model.toJSON.apply(model, _.rest(arguments)), {
            externalUrl: 'url'
          });
        }
      }

    } );

  } );
<|endoftext|>


<commit_before>// You are a professional robber planning to rob houses along a street.
// Each house has a certain amount of money stashed, the only constraint stopping you from
// robbing each of them is that adjacent houses have security system connected and
// it will automatically contact the police if two adjacent houses were broken into on the same night.

// Given a list of non-negative integers representing the amount of money of each house,
// determine the maximum amount of money you can rob tonight without alerting the police.

// Input: Array
// ex. [5,2,3,6]
//     []
//     [1]

// Output: Integer

//     12
//     0
//     1

var rob = function(nums) {
    if( nums.length < 1 ) return 0;
    if( nums.length === 1 ) return nums[0];
    nums[1] = Math.max( nums[0], nums[1] );

    for( var i = 2; i < nums.length; i++ ){
        nums[i] = Math.max( nums[i-2] + nums[i], nums[i - 1] );
    }
    return nums[nums.length - 1];
};
<commit_msg>add solution<commit_after>// You are a professional robber planning to rob houses along a street.
// Each house has a certain amount of money stashed, the only constraint stopping you from
// robbing each of them is that adjacent houses have security system connected and
// it will automatically contact the police if two adjacent houses were broken into on the same night.

// Given a list of non-negative integers representing the amount of money of each house,
// determine the maximum amount of money you can rob tonight without alerting the police.

// Input: Array
// ex. [5,2,3,6]
//     []
//     [1]

// Output: Integer

//     12
//     0
//     1

var rob = function(nums) {
    if( nums.length < 1 ) return 0;
    if( nums.length === 1 ) return nums[0];
    nums[1] = Math.max( nums[0], nums[1] );

    for( var i = 2; i < nums.length; i++ ){
        nums[i] = Math.max( nums[i-2] + nums[i], nums[i - 1] );
    }
    return nums[nums.length - 1];
};

var rob = function(nums) {
    return nums.reduce(function(p, n) {
        return [p[1], Math.max(p[0] + n, p[1])];
    }, [0,0])[1];
};
<|endoftext|>


<commit_before>/*

jquery.aggregate.js by Greg Brown 2011. See
http://gregbrown.co.nz/code/jquery-aggregate/ for details.

License information: http://gregbrown.co.nz/code/license/

*/

/*

Find the aggregate of a certain property across a jquery element
collection. Eg to find the maximum height of a group of elements:

$('.elements').aggregate('height', 'max');

to find the first non-zero height from a group of elements:

$('.elements').aggregate('height', function() {
    for (var i = 0; i < arguments.length; i++) {
        if (arguments[i]) {
            return arguments[i];
        }
    }
});

property: any callable jquery element property, eg. 'height',
      'outerWidth', 'scrollTop' etc, or a callable taking the element
      as its sole argument.
type: 'max', 'min', 'sum', or a callable taking a variable number of arguments
      to be aggregated

*/

$.fn.aggregate = (function(property, type){
    if (typeof property === 'function') {
        var values = this.map(function () {
            return property($(this));
        });
    }
    else {
        var values = this.map(function () {
            return $(this)[property]();
        });
    }
    if (type === 'sum') {
        var sum = 0;
        for (var i = 0; i < values.length; i++) {
            sum += values[i];
        }
        return sum;
    }
    else if (typeof type === 'function') {
        return type.apply(null, values.get());
    }
    else {
        return Math[type].apply(null, values.get());
    }
});

/*

Normalize a certain property across a jquery element collection, with
optional grouping into rows.
Eg to make a group of elements all the same height as the highest, in
rows of 4 elements each:

$('.elements').normalize({
    property: 'height',
    type: 'max',
    per_row: $('.elements').parent().width() + 'px',
    callback: function(el, val) {
        el.css('paddingTop', val - el.height() + 'px');
    }
});

property: any callable jquery element property (default 'height') or
      callable taking the element as its sole argument.
type: 'max', 'min', or a callable taking a variable number of
      arguments to be aggregated (default 'max')
per_row: number of elements in a row as an int, or a width in pixels,
         e.g. '300px'. (default is to normalize all elements as one)
callback: used to apply the aggregate to each element. (default
          is to use the same method specified in the property option.

*/

$.fn.normalize = (function(options){
    if (this.length) {
        var els, agg,
            options = $.extend({
                property: 'height',
                type: 'max',
                per_row: this.length,
                callback: function(el, val) {
                    el.css((options.property === 'height' ? 'minHeight' : options.property), val + 'px');
                }
            }, options);

        function row_item_count(items) {
            /* Get the number of items in the row - either the static per_row value,
               or the number of items that can be fitted within the per_row width. */
            if (typeof options.per_row === 'string' && options.per_row.slice(-2) === 'px') {
                var j = 0,
                    width = items.eq(0).outerWidth(true);

                while (width <= parseInt(options.per_row) && j < items.length) {
                    if (j + 1 < items.length) {
                        width += items.eq(j + 1).outerWidth(true);
                    }
                    j++;
                }

                // at least one item per row, regardless of its length
                return Math.max(j, 1);
            }
            else {
                return options.per_row || items.length;
            }
        };

        var i = 0,
            items_per_row;
        while (i < this.length) {
            items_per_row = row_item_count(this.slice(i));

            els = this.slice(i, i + items_per_row);
            agg = els.aggregate(options.property, options.type);
            els.each(function() {
                options.callback($(this), agg);
            });
            i += items_per_row;
        }
    }
    return this;
});

<commit_msg>allow arguments to property calls, eg outerHeight(true)<commit_after>/*

jquery.aggregate.js by Greg Brown 2011. See
http://gregbrown.co.nz/code/jquery-aggregate/ for details.

License information: http://gregbrown.co.nz/code/license/

*/

/*

Find the aggregate of a certain property across a jquery element
collection. Eg to find the maximum height of a group of elements:

$('.elements').aggregate('height', 'max');

to find the first non-zero height from a group of elements:

$('.elements').aggregate('height', function() {
    for (var i = 0; i < arguments.length; i++) {
        if (arguments[i]) {
            return arguments[i];
        }
    }
});

property: any callable jquery element property, eg. 'height',
      'outerWidth', 'scrollTop' etc, or a callable taking the element
      as its sole argument, or an array where the first item is the callable
      and subsequent items are the arguments to be passed, i.e.
      `['outerHeight', true]`.
type: 'max', 'min', 'sum', or a callable taking a variable number of arguments
      to be aggregated

*/

$.fn.aggregate = (function(property, type){
    if (typeof property === 'function') {
        var values = this.map(function () {
            return property($(this));
        });
    }
    else {
        if (typeof property === 'string') {
            property = [property];
        }
        var values = this.map(function () {
            return $(this)[property[0]].apply($(this), property.slice(1));
        });
    }
    if (type === 'sum') {
        var sum = 0;
        for (var i = 0; i < values.length; i++) {
            sum += values[i];
        }
        return sum;
    }
    else if (typeof type === 'function') {
        return type.apply(null, values.get());
    }
    else {
        return Math[type].apply(null, values.get());
    }
});

/*

Normalize a certain property across a jquery element collection, with
optional grouping into rows.
Eg to make a group of elements all the same height as the highest, in
rows of 4 elements each:

$('.elements').normalize({
    property: 'height',
    type: 'max',
    per_row: $('.elements').parent().width() + 'px',
    callback: function(el, val) {
        el.css('paddingTop', val - el.height() + 'px');
    }
});

property: any callable jquery element property (default 'height') or
      callable taking the element as its sole argument.
type: 'max', 'min', or a callable taking a variable number of
      arguments to be aggregated (default 'max')
per_row: number of elements in a row as an int, or a width in pixels,
         e.g. '300px'. (default is to normalize all elements as one)
callback: used to apply the aggregate to each element. (default
          is to use the same method specified in the property option.

*/

$.fn.normalize = (function(options){
    if (this.length) {
        var els, agg,
            options = $.extend({
                property: 'height',
                type: 'max',
                per_row: this.length,
                callback: function(el, val) {
                    el.css((options.property === 'height' ? 'minHeight' : options.property), val + 'px');
                }
            }, options);

        function row_item_count(items) {
            /* Get the number of items in the row - either the static per_row value,
               or the number of items that can be fitted within the per_row width. */
            if (typeof options.per_row === 'string' && options.per_row.slice(-2) === 'px') {
                var j = 0,
                    width = items.eq(0).outerWidth(true);

                while (width <= parseInt(options.per_row) && j < items.length) {
                    if (j + 1 < items.length) {
                        width += items.eq(j + 1).outerWidth(true);
                    }
                    j++;
                }

                // at least one item per row, regardless of its length
                return Math.max(j, 1);
            }
            else {
                return options.per_row || items.length;
            }
        };

        var i = 0,
            items_per_row;
        while (i < this.length) {
            items_per_row = row_item_count(this.slice(i));

            els = this.slice(i, i + items_per_row);
            agg = els.aggregate(options.property, options.type);
            els.each(function() {
                options.callback($(this), agg);
            });
            i += items_per_row;
        }
    }
    return this;
});

<|endoftext|>


<commit_before>var passport = require('passport')
  , path     = require('path')
  , url      = require('url');

/**
 * Passport Service
 *
 * A painless Passport.js service for your Sails app that is guaranteed to
 * Rock Your Socks™. It takes all the hassle out of setting up Passport.js by
 * encapsulating all the boring stuff in two functions:
 *
 *   passport.endpoint()
 *   passport.callback()
 *
 * The former sets up an endpoint (/auth/:provider) for redirecting a user to a
 * third-party provider for authentication, while the latter sets up a callback
 * endpoint (/auth/:provider/callback) for receiving the response from the
 * third-party provider. All you have to do is define in the configuration which
 * third-party providers you'd like to support. It's that easy!
 *
 * Behind the scenes, the service stores all the data it needs within "Pass-
 * ports". These contain all the information required to associate a local user
 * with a profile from a third-party provider. This even holds true for the good
 * ol' password authentication scheme – the Authentication Service takes care of
 * encrypting passwords and storing them in Passports, allowing you to keep your
 * User model free of bloat.
 */

// Load authentication protocols
passport.protocols = require('./protocols');

/**
 * Connect a third-party profile to a local user
 *
 * This is where most of the magic happens when a user is authenticating with a
 * third-party provider. What it does, is the following:
 *
 *   1. Given a provider and an identifier, find a mathcing Passport.
 *   2. From here, the logic branches into two paths.
 *
 *     - A user is not currently logged in:
 *       1. If a Passport wassn't found, create a new user as well as a new
 *          Passport that will be assigned to the user.
 *       2. If a Passport was found, get the user associated with the passport.
 *
 *     - A user is currently logged in:
 *       1. If a Passport wasn't found, create a new Passport and associate it
 *          with the already logged in user (ie. "Connect")
 *       2. If a Passport was found, nothing needs to happen.
 *
 * As you can see, this function handles both "authentication" and "authori-
 * zation" at the same time. This is due to the fact that we pass in
 * `passReqToCallback: true` when loading the strategies, allowing us to look
 * for an existing session in the request and taking action based on that.
 *
 * For more information on auth(entication|rization) in Passport.js, check out:
 * http://passportjs.org/guide/authenticate/
 * http://passportjs.org/guide/authorize/
 *
 * @param {Object}   req
 * @param {Object}   query
 * @param {Object}   profile
 * @param {Function} next
 */
passport.connect = function (req, query, profile, next) {
  var strategies = sails.config.passport
    , config     = strategies[profile.provider]
    , user       = {};

  // Set the authentication provider.
  query.provider = req.param('provider');

  // If the profile object contains a list of emails, grab the first one and
  // add it to the user.
  if (profile.hasOwnProperty('emails')) {
    user.email = profile.emails[0].value;
  }
  // If the profile object contains a username, add it to the user.
  if (profile.hasOwnProperty('username')) {
    user.username = profile.username;
  }

  // If neither an email or a username was available in the profile, we don't
  // have a way of identifying the user in the future. Throw an error and let
  // whoever's next in the line take care of it.
  if (!Object.keys(user).length) {
    return next(new Error('Neither a username or email was available', null));
  }

  Passport.findOne({
    provider   : profile.provider
  , identifier : query.identifier.toString()
  }, function (err, passport) {
    if (err) return next(err);

    if (!req.user) {
      // Scenario: A new user is attempting to sign up using a third-party
      //           authentication provider.
      // Action:   Create a new user and assign them a passport.
      if (!passport) {
        User.create(user, function (err, user) {
          if (err) return next(err);

          query.user = user.id;

          Passport.create(query, function (err, passport) {
            // If a passport wasn't created, bail out
            if (err) return next(err);

            next(err, user);
          });
        });
      }
      // Scenario: An existing user is trying to log in using an already
      //           connected passport.
      // Action:   Get the user associated with the passport.
      else {
        // If the tokens have changed since the last session, update them
        if (query.hasOwnProperty('tokens') && query.tokens !== passport.tokens) {
          passport.tokens = query.tokens;
        }

        // Save any updates to the Passport before moving on
        passport.save(function (err, passport) {
          if (err) return next(err);

          // Fetch the user associated with the Passport
          User.findOne(passport.user, next);
        });
      }
    } else {
      // Scenario: A user is currently logged in and trying to connect a new
      //           passport.
      // Action:   Create and assign a new passport to the user.
      if (!passport) {
        query.user = req.user.id;

        Passport.create(query, function (err, passport) {
          // If a passport wasn't created, bail out
          if (err) return next(err);

          next(err, req.user);
        });
      }
      // Scenario: The user is a nutjob or spammed the back-button.
      // Action:   Simply pass along the already established session.
      else {
        next(null, req.user);
      }
    }
  });
};

/**
 * Create an authentication endpoint
 *
 * For more information on authentication in Passport.js, check out:
 * http://passportjs.org/guide/authenticate/
 *
 * @param  {Object} req
 * @param  {Object} res
 */
passport.endpoint = function (req, res) {
  var strategies = sails.config.passport
    , provider   = req.param('provider')
    , options    = {};

  // If a provider doesn't exist for this endpoint, send the user back to the
  // login page
  if (!strategies.hasOwnProperty(provider)) {
    return res.redirect('/login');
  }

  // Attach scope if it has been set in the config
  if (strategies[provider].hasOwnProperty('scope')) {
    options.scope = strategies[provider].scope;
  }

  // Load authentication strategies
  this.loadStrategies(req);

  // Redirect the user to the provider for authentication. When complete,
  // the provider will redirect the user back to the application at
  //     /auth/:provider/callback
  this.authenticate(provider, options)(req, res, req.next);
};

/**
 * Create an authentication callback endpoint
 *
 * For more information on authentication in Passport.js, check out:
 * http://passportjs.org/guide/authenticate/
 *
 * @param {Object}   req
 * @param {Object}   res
 * @param {Function} next
 */
passport.callback = function (req, res, next) {
  var provider = req.param('provider', 'local')
    , action   = req.param('action');

  // Passport.js wasn't really built for local user registration, but it's nice
  // having it tied into everything else.
  if (provider === 'local' && action !== undefined) {
    if (action === 'register' && !req.user) {
      this.protocols.local.register(req, res, next);
    }
    else if (action === 'connect' && req.user) {
      this.protocols.local.connect(req, res, next);
    }
    else {
      next(new Error('Invalid action'));
    }
  } else {
    // Load authentication strategies
    this.loadStrategies(req);

    // The provider will redirect the user to this URL after approval. Finish
    // the authentication process by attempting to obtain an access token. If
    // access was granted, the user will be logged in. Otherwise, authentication
    // has failed.
    this.authenticate(provider, next)(req, res, req.next);
  }
};

/**
 * Load all strategies defined in the Passport configuration
 *
 * For example, we could add this to our config to use the GitHub strategy
 * with permission to access a users email address (even if it's marked as
 * private) as well as permission to add and update a user's Gists:
 *
    github: {
      name: 'GitHub',
      protocol: 'oauth2',
      scope: [ 'user', 'gist' ]
      options: {
        clientID: 'CLIENT_ID',
        clientSecret: 'CLIENT_SECRET'
      }
    }
 *
 * For more information on the providers supported by Passport.js, check out:
 * http://passportjs.org/guide/providers/
 *
 * @param {Object} req
 */
passport.loadStrategies = function (req) {
  var self       = this
    , strategies = sails.config.passport;

  Object.keys(strategies).forEach(function (key) {
    var options = { passReqToCallback: true }, Strategy;

    if (key === 'local') {
      // Since we need to allow users to login using both usernames as well as
      // emails, we'll set the username field to something more generic.
      _.extend(options, { usernameField: 'identifier' });

      // Only load the local strategy if it's enabled in the config
      if (strategies.local) {
        Strategy = strategies[key].strategy;

        self.use(new Strategy(options, self.protocols.local.login));
      }
    } else {
      var protocol = strategies[key].protocol
        , callback = strategies[key].callback;

      if (!callback) {
        callback = path.join('auth', key, 'callback');
      }

      Strategy = strategies[key].strategy;

      switch (protocol) {
        case 'oauth':
        case 'oauth2':
          options.callbackURL = url.resolve(req.baseUrl, callback);
          break;

        case 'openid':
          options.returnURL = url.resolve(req.baseUrl, callback);
          options.realm     = req.baseUrl;
          options.profile   = true;
          break;
      }

      // Merge the default options with any options defined in the config. All
      // defaults can be overriden, but I don't see a reason why you'd want to
      // do that.
      _.extend(options, strategies[key].options);

      self.use(new Strategy(options, self.protocols[protocol]));
    }
  });
};

passport.serializeUser(function (user, next) {
  next(null, user.id);
});

passport.deserializeUser(function (id, next) {
  User.findOne(id, next);
});

module.exports = passport;
<commit_msg>Fix possible bug (#31)<commit_after>var passport = require('passport')
  , path     = require('path')
  , url      = require('url');

/**
 * Passport Service
 *
 * A painless Passport.js service for your Sails app that is guaranteed to
 * Rock Your Socks™. It takes all the hassle out of setting up Passport.js by
 * encapsulating all the boring stuff in two functions:
 *
 *   passport.endpoint()
 *   passport.callback()
 *
 * The former sets up an endpoint (/auth/:provider) for redirecting a user to a
 * third-party provider for authentication, while the latter sets up a callback
 * endpoint (/auth/:provider/callback) for receiving the response from the
 * third-party provider. All you have to do is define in the configuration which
 * third-party providers you'd like to support. It's that easy!
 *
 * Behind the scenes, the service stores all the data it needs within "Pass-
 * ports". These contain all the information required to associate a local user
 * with a profile from a third-party provider. This even holds true for the good
 * ol' password authentication scheme – the Authentication Service takes care of
 * encrypting passwords and storing them in Passports, allowing you to keep your
 * User model free of bloat.
 */

// Load authentication protocols
passport.protocols = require('./protocols');

/**
 * Connect a third-party profile to a local user
 *
 * This is where most of the magic happens when a user is authenticating with a
 * third-party provider. What it does, is the following:
 *
 *   1. Given a provider and an identifier, find a mathcing Passport.
 *   2. From here, the logic branches into two paths.
 *
 *     - A user is not currently logged in:
 *       1. If a Passport wassn't found, create a new user as well as a new
 *          Passport that will be assigned to the user.
 *       2. If a Passport was found, get the user associated with the passport.
 *
 *     - A user is currently logged in:
 *       1. If a Passport wasn't found, create a new Passport and associate it
 *          with the already logged in user (ie. "Connect")
 *       2. If a Passport was found, nothing needs to happen.
 *
 * As you can see, this function handles both "authentication" and "authori-
 * zation" at the same time. This is due to the fact that we pass in
 * `passReqToCallback: true` when loading the strategies, allowing us to look
 * for an existing session in the request and taking action based on that.
 *
 * For more information on auth(entication|rization) in Passport.js, check out:
 * http://passportjs.org/guide/authenticate/
 * http://passportjs.org/guide/authorize/
 *
 * @param {Object}   req
 * @param {Object}   query
 * @param {Object}   profile
 * @param {Function} next
 */
passport.connect = function (req, query, profile, next) {
  var strategies = sails.config.passport
    , config     = strategies[profile.provider]
    , user       = {};

  // Set the authentication provider.
  query.provider = req.param('provider');

  // If the profile object contains a list of emails, grab the first one and
  // add it to the user.
  if (profile.hasOwnProperty('emails')) {
    user.email = profile.emails[0].value;
  }
  // If the profile object contains a username, add it to the user.
  if (profile.hasOwnProperty('username')) {
    user.username = profile.username;
  }

  // If neither an email or a username was available in the profile, we don't
  // have a way of identifying the user in the future. Throw an error and let
  // whoever's next in the line take care of it.
  if (!user.username && !user.email) {
    return next(new Error('Neither a username nor email was available'));
  }

  Passport.findOne({
    provider   : profile.provider
  , identifier : query.identifier.toString()
  }, function (err, passport) {
    if (err) return next(err);

    if (!req.user) {
      // Scenario: A new user is attempting to sign up using a third-party
      //           authentication provider.
      // Action:   Create a new user and assign them a passport.
      if (!passport) {
        User.create(user, function (err, user) {
          if (err) return next(err);

          query.user = user.id;

          Passport.create(query, function (err, passport) {
            // If a passport wasn't created, bail out
            if (err) return next(err);

            next(err, user);
          });
        });
      }
      // Scenario: An existing user is trying to log in using an already
      //           connected passport.
      // Action:   Get the user associated with the passport.
      else {
        // If the tokens have changed since the last session, update them
        if (query.hasOwnProperty('tokens') && query.tokens !== passport.tokens) {
          passport.tokens = query.tokens;
        }

        // Save any updates to the Passport before moving on
        passport.save(function (err, passport) {
          if (err) return next(err);

          // Fetch the user associated with the Passport
          User.findOne(passport.user, next);
        });
      }
    } else {
      // Scenario: A user is currently logged in and trying to connect a new
      //           passport.
      // Action:   Create and assign a new passport to the user.
      if (!passport) {
        query.user = req.user.id;

        Passport.create(query, function (err, passport) {
          // If a passport wasn't created, bail out
          if (err) return next(err);

          next(err, req.user);
        });
      }
      // Scenario: The user is a nutjob or spammed the back-button.
      // Action:   Simply pass along the already established session.
      else {
        next(null, req.user);
      }
    }
  });
};

/**
 * Create an authentication endpoint
 *
 * For more information on authentication in Passport.js, check out:
 * http://passportjs.org/guide/authenticate/
 *
 * @param  {Object} req
 * @param  {Object} res
 */
passport.endpoint = function (req, res) {
  var strategies = sails.config.passport
    , provider   = req.param('provider')
    , options    = {};

  // If a provider doesn't exist for this endpoint, send the user back to the
  // login page
  if (!strategies.hasOwnProperty(provider)) {
    return res.redirect('/login');
  }

  // Attach scope if it has been set in the config
  if (strategies[provider].hasOwnProperty('scope')) {
    options.scope = strategies[provider].scope;
  }

  // Load authentication strategies
  this.loadStrategies(req);

  // Redirect the user to the provider for authentication. When complete,
  // the provider will redirect the user back to the application at
  //     /auth/:provider/callback
  this.authenticate(provider, options)(req, res, req.next);
};

/**
 * Create an authentication callback endpoint
 *
 * For more information on authentication in Passport.js, check out:
 * http://passportjs.org/guide/authenticate/
 *
 * @param {Object}   req
 * @param {Object}   res
 * @param {Function} next
 */
passport.callback = function (req, res, next) {
  var provider = req.param('provider', 'local')
    , action   = req.param('action');

  // Passport.js wasn't really built for local user registration, but it's nice
  // having it tied into everything else.
  if (provider === 'local' && action !== undefined) {
    if (action === 'register' && !req.user) {
      this.protocols.local.register(req, res, next);
    }
    else if (action === 'connect' && req.user) {
      this.protocols.local.connect(req, res, next);
    }
    else {
      next(new Error('Invalid action'));
    }
  } else {
    // Load authentication strategies
    this.loadStrategies(req);

    // The provider will redirect the user to this URL after approval. Finish
    // the authentication process by attempting to obtain an access token. If
    // access was granted, the user will be logged in. Otherwise, authentication
    // has failed.
    this.authenticate(provider, next)(req, res, req.next);
  }
};

/**
 * Load all strategies defined in the Passport configuration
 *
 * For example, we could add this to our config to use the GitHub strategy
 * with permission to access a users email address (even if it's marked as
 * private) as well as permission to add and update a user's Gists:
 *
    github: {
      name: 'GitHub',
      protocol: 'oauth2',
      scope: [ 'user', 'gist' ]
      options: {
        clientID: 'CLIENT_ID',
        clientSecret: 'CLIENT_SECRET'
      }
    }
 *
 * For more information on the providers supported by Passport.js, check out:
 * http://passportjs.org/guide/providers/
 *
 * @param {Object} req
 */
passport.loadStrategies = function (req) {
  var self       = this
    , strategies = sails.config.passport;

  Object.keys(strategies).forEach(function (key) {
    var options = { passReqToCallback: true }, Strategy;

    if (key === 'local') {
      // Since we need to allow users to login using both usernames as well as
      // emails, we'll set the username field to something more generic.
      _.extend(options, { usernameField: 'identifier' });

      // Only load the local strategy if it's enabled in the config
      if (strategies.local) {
        Strategy = strategies[key].strategy;

        self.use(new Strategy(options, self.protocols.local.login));
      }
    } else {
      var protocol = strategies[key].protocol
        , callback = strategies[key].callback;

      if (!callback) {
        callback = path.join('auth', key, 'callback');
      }

      Strategy = strategies[key].strategy;

      switch (protocol) {
        case 'oauth':
        case 'oauth2':
          options.callbackURL = url.resolve(req.baseUrl, callback);
          break;

        case 'openid':
          options.returnURL = url.resolve(req.baseUrl, callback);
          options.realm     = req.baseUrl;
          options.profile   = true;
          break;
      }

      // Merge the default options with any options defined in the config. All
      // defaults can be overriden, but I don't see a reason why you'd want to
      // do that.
      _.extend(options, strategies[key].options);

      self.use(new Strategy(options, self.protocols[protocol]));
    }
  });
};

passport.serializeUser(function (user, next) {
  next(null, user.id);
});

passport.deserializeUser(function (id, next) {
  User.findOne(id, next);
});

module.exports = passport;
<|endoftext|>


<commit_before>// ==UserScript==
// @name         Ads DOM Remover
// @namespace    sagiegurari
// @version      1.02
// @author       Sagie Gur-Ari
// @description  Removes Ad Containers from DOM (doesn't replace adblocker extension, but blocks dynamic content which the adblocker fails to block by removing whole sections from the HTML DOM.)
// @homepage     https://github.com/sagiegurari/userscripts-ads-dom-remover
// @supportURL   https://github.com/sagiegurari/userscripts-ads-dom-remover/issues
// @match        http://www.ynet.co.il/home/*
// @match        http://www.ynet.co.il/articles/*
// @match        http://www.mynet.co.il/articles/*
// @match        http://www.calcalist.co.il/*
// @match        http://www.globes.co.il/*
// @match        https://sourceforge.net/projects/*/download*
// @match        https://sourceforge.net/projects/*/postdownload*
// @match        http://subscenter.cinemast.com/*
// @match        http://www.subscenter.co/*
// @match        http://www.subscenter.org/*
// @match        https://*.wikipedia.org/*
// @match        http://www.opensubtitles.org/*
// @require      https://code.jquery.com/jquery-2.2.2.min.js
// @require      https://greasyfork.org/scripts/18490-ads-dom-remover-runner/code/Ads%20DOM%20Remover%20Runner.js?version=162071
// @grant        none
// @license      MIT License
// ==/UserScript==

(function run($, runner) {
    'use strict';

    var selectorDefinitions = {
        ynet: {
            hostNames: ['ynet', 'calcalist'],
            selectors: [
                '#colorbox',
                '#cboxOverlay',
                '#ads.premium',
                '#articleLayoutrightsidtable',
                '#google_image_div',
                'img[src*="dynamicyield"]',
                'div.MSCmainContent',
                '[id*="arketingCarouse"]',
                '[id*="arketingRecommended"]',
                '.mainVerticalArticleSharingLinks',
                '.OUTBRAIN',
                '.topBannerWrap',
                '.block.B3 .B3.ghcite.dyother.dyMonitor div',
                '.bigdealhomepage',
                '#ww6s_Main',
                '.buyandsavedy',
                '.area.footer.ghcite',
                '.hdr_set_homepage',
                '#c1_Hor',
                '#c2_Hor',
                '#c3_Hor',
                '#c4_Hor',
                '#c5_Hor',
                '#c6_Hor',
                '.homepagevideo-x6',
                '.buyandsave',
                '.general-image',
                '.PhotoArticlesTalkbacks',
                '[name="ExternalWebpageIframe"]',
                '#PROCOIL_SearchForm',
                '#magazines1024',
                '[id^="promo_"]',
                '[id^="ads."]',
                '[class*="facebook"]',
                '.main_search_radio',
                'tr td [id^="ads."]',
                '.art-action-wrp',
                '.header-user-profile',
                '.left-art-content',
                '[class*="GeneralBanner"]',
                '#vilon',
                '#prime.shook',
                {
                    selector: '.homepagelitevideo',
                    fineTuneSelector: function ($element) {
                        return $element.parent().parent();
                    }
                },
                {
                    selector: 'iframe',
                    filter: function ($element) {
                        return !$element.parent().hasClass('news_ticker_iframe');
                    }
                },
                {
                    selector: 'div.B2b.block div',
                    pre: function ($element) {
                        $element.parent().css({
                            height: '1px'
                        });
                    }
                }
            ]
        },
        globes: {
            hostNames: 'globes',
            selectors: [
                '#chromeWindow',
                {
                    selector: 'iframe',
                    filter: function ($element) {
                        var id = $element.attr('id');
                        var src = $element.attr('src') || '';

                        return (id !== 'GlobalFinanceData_home') && (src.indexOf('/news/') !== -1);
                    }
                }
            ]
        },
        sourceforge: {
            hostNames: 'sourceforge.net',
            selectors: [
                '#content-for-adblock',
                '#newsletter-floating',
                '#page-body'
            ]
        },
        subscenter: {
            hostNames: 'subscenter',
            selectors: [
                '.weekBottom',
                '.reviewsWindow',
                '#banner_cinemast',
                '.bottomMenu',
                'footer',
                '#paypal',
                '#aboveSite',
                {
                    selector: '#subtitles_list a[href="/he/contactus/"]',
                    fineTuneSelector: function ($element) {
                        return $element.parent();
                    }
                }
            ]
        },
        wikipedia: {
            hostNames: 'wikipedia.org',
            selectors: [
                '#frbanner',
                '#wlm-banner',
                '.frbanner'
            ]
        },
        opensubtitles: {
            hostNames: 'opensubtitles',
            selectors: [
                '.rec_container_right'
            ]
        }
    };

    [
        '#dcPremiumRightImg',
        '.boulevard',
        '#multiarticles-9',
        '#multiarticles-12',
        '#multiarticles-13',
        '#multiarticles-14',
        '#multiarticles-15',
        '#multiarticles-16',
        '.CdaMostViews',
        '.CdaCalcalistToday',
        '.CdaRecomendedMovies',
        '#SpecialBuilder1280',
        '.cdaFooter1280'
    ].forEach(function addSelector(selector) {
        selectorDefinitions.ynet.selectors.push({
            selector: selector,
            fineTuneSelector: function ($element) {
                return $element.parent();
            }
        });
    });

    runner($, {
        getSelectorDefinitions: function () {
            return selectorDefinitions;
        }
    });
}(window.jQuery.noConflict(true), window.adrRunner));
<commit_msg>more selectors<commit_after>// ==UserScript==
// @name         Ads DOM Remover
// @namespace    sagiegurari
// @version      1.03
// @author       Sagie Gur-Ari
// @description  Removes Ad Containers from DOM (doesn't replace adblocker extension, but blocks dynamic content which the adblocker fails to block by removing whole sections from the HTML DOM.)
// @homepage     https://github.com/sagiegurari/userscripts-ads-dom-remover
// @supportURL   https://github.com/sagiegurari/userscripts-ads-dom-remover/issues
// @match        http://www.ynet.co.il/home/*
// @match        http://www.ynet.co.il/articles/*
// @match        http://www.mynet.co.il/articles/*
// @match        http://www.calcalist.co.il/*
// @match        http://www.globes.co.il/*
// @match        https://sourceforge.net/projects/*/download*
// @match        https://sourceforge.net/projects/*/postdownload*
// @match        http://subscenter.cinemast.com/*
// @match        http://www.subscenter.co/*
// @match        http://www.subscenter.org/*
// @match        https://*.wikipedia.org/*
// @match        http://www.opensubtitles.org/*
// @require      https://code.jquery.com/jquery-2.2.2.min.js
// @require      https://greasyfork.org/scripts/18490-ads-dom-remover-runner/code/Ads%20DOM%20Remover%20Runner.js?version=162071
// @grant        none
// @license      MIT License
// ==/UserScript==

(function run($, runner) {
    'use strict';

    var selectorDefinitions = {
        ynet: {
            hostNames: ['ynet', 'calcalist'],
            selectors: [
                '#colorbox',
                '#cboxOverlay',
                '#ads.premium',
                '#articleLayoutrightsidtable',
                '#google_image_div',
                'img[src*="dynamicyield"]',
                'div.MSCmainContent',
                '[id*="arketingCarouse"]',
                '[id*="arketingRecommended"]',
                '.mainVerticalArticleSharingLinks',
                '.OUTBRAIN',
                '.topBannerWrap',
                '.block.B3 .B3.ghcite.dyother.dyMonitor div',
                '.bigdealhomepage',
                '#ww6s_Main',
                '.buyandsavedy',
                '.area.footer.ghcite',
                '.hdr_set_homepage',
                '#c1_Hor',
                '#c2_Hor',
                '#c3_Hor',
                '#c4_Hor',
                '#c5_Hor',
                '#c6_Hor',
                '.homepagevideo-x6',
                '.buyandsave',
                '.general-image',
                '.PhotoArticlesTalkbacks',
                '[name="ExternalWebpageIframe"]',
                '#PROCOIL_SearchForm',
                '#magazines1024',
                '[id^="promo_"]',
                '[id^="ads."]',
                '[class*="facebook"]',
                '.main_search_radio',
                'tr td [id^="ads."]',
                '.art-action-wrp',
                '.header-user-profile',
                '.left-art-content',
                '[class*="GeneralBanner"]',
                '#vilon',
                '#prime.shook',
                '#articlebottomsharinglinks',
                {
                    selector: '.homepagelitevideo',
                    fineTuneSelector: function ($element) {
                        return $element.parent().parent();
                    }
                },
                {
                    selector: 'iframe',
                    filter: function ($element) {
                        return !$element.parent().hasClass('news_ticker_iframe');
                    }
                },
                {
                    selector: 'div.B2b.block div',
                    pre: function ($element) {
                        $element.parent().css({
                            height: '1px'
                        });
                    }
                }
            ]
        },
        globes: {
            hostNames: 'globes',
            selectors: [
                '#chromeWindow',
                {
                    selector: 'iframe',
                    filter: function ($element) {
                        var id = $element.attr('id');
                        var src = $element.attr('src') || '';

                        return (id !== 'GlobalFinanceData_home') && (src.indexOf('/news/') !== -1);
                    }
                }
            ]
        },
        sourceforge: {
            hostNames: 'sourceforge.net',
            selectors: [
                '#content-for-adblock',
                '#newsletter-floating',
                '#page-body'
            ]
        },
        subscenter: {
            hostNames: 'subscenter',
            selectors: [
                '.weekBottom',
                '.reviewsWindow',
                '#banner_cinemast',
                '.bottomMenu',
                'footer',
                '#paypal',
                '#aboveSite',
                {
                    selector: '#subtitles_list a[href="/he/contactus/"]',
                    fineTuneSelector: function ($element) {
                        return $element.parent();
                    }
                }
            ]
        },
        wikipedia: {
            hostNames: 'wikipedia.org',
            selectors: [
                '#frbanner',
                '#wlm-banner',
                '.frbanner'
            ]
        },
        opensubtitles: {
            hostNames: 'opensubtitles',
            selectors: [
                '.rec_container_right'
            ]
        }
    };

    [
        '#dcPremiumRightImg',
        '.boulevard',
        '#multiarticles-9',
        '#multiarticles-12',
        '#multiarticles-13',
        '#multiarticles-14',
        '#multiarticles-15',
        '#multiarticles-16',
        '.CdaMostViews',
        '.CdaCalcalistToday',
        '.CdaRecomendedMovies',
        '#SpecialBuilder1280',
        '.cdaFooter1280'
    ].forEach(function addSelector(selector) {
        selectorDefinitions.ynet.selectors.push({
            selector: selector,
            fineTuneSelector: function ($element) {
                return $element.parent();
            }
        });
    });

    runner($, {
        getSelectorDefinitions: function () {
            return selectorDefinitions;
        }
    });
}(window.jQuery.noConflict(true), window.adrRunner));
<|endoftext|>