<commit_before>/*
 * slider_events.js
 */
(function($) {

module( "slider: events" );

//Specs from http://wiki.jqueryui.com/Slider#specs
//"change callback: triggers when the slider has stopped moving and has a new
// value (even if same as previous value), via mouse(mouseup) or keyboard(keyup)
// or value method/option"
test( "mouse based interaction", function() {
	expect(4);

	var el = $( "#slider1" )
		.slider({
			start: function( event ) {
				equal( event.originalEvent.type, "mousedown", "start triggered by mousedown" );
			},
			slide: function( event) {
				equal( event.originalEvent.type, "mousemove", "slider triggered by mousemove" );
			},
			stop: function( event ) {
				equal( event.originalEvent.type, "mouseup", "stop triggered by mouseup" );
			},
			change: function( event ) {
				equal( event.originalEvent.type, "mouseup", "change triggered by mouseup" );
			}
		});

	el.find( ".ui-slider-handle" ).eq( 0 )
		.simulate( "drag", { dx: 10, dy: 10 } );

});
test( "keyboard based interaction", function() {
	expect(3);

	// Test keyup at end of handle slide (keyboard)
	var el = $( "#slider1" )
		.slider({
			start: function( event ) {
				equal( event.originalEvent.type, "keydown", "start triggered by keydown" );
			},
			slide: function() {
				ok( false, "Slider never triggered by keys" );
			},
			stop: function( event ) {
				equal( event.originalEvent.type, "keyup", "stop triggered by keyup" );
			},
			change: function( event ) {
				equal( event.originalEvent.type, "keyup", "change triggered by keyup" );
			}
		});

	el.find( ".ui-slider-handle" ).eq( 0 )
		.simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } )
		.simulate( "keypress", { keyCode: $.ui.keyCode.LEFT } )
		.simulate( "keyup", { keyCode: $.ui.keyCode.LEFT } );

});
test( "programmatic event triggers", function() {
	expect(6);

	// Test value method
	var el = $( "

" )
		.slider({
			change: function() {
				ok( true, "change triggered by value method" );
			}
		})
		.slider( "value", 0 );

	QUnit.reset();
	// Test values method
	el = $( "

" )
		.slider({
			values: [ 10, 20 ],
			change: function() {
				ok( true, "change triggered by values method" );
			}
		})
		.slider( "values", [80, 90] );

	QUnit.reset();
	// Test value option
	el = $( "

" )
		.slider({
			change: function() {
				ok( true, "change triggered by value option" );
			}
		})
		.slider( "option", "value", 0 );

	QUnit.reset();
	// Test values option
	el = $( "

" )
		.slider({
			values: [ 10, 20 ],
			change: function() {
				ok( true, "change triggered by values option" );
			}
		})
		.slider( "option", "values", [80, 90] );

});

test( "mouse based interaction part two: when handles overlap", function() {
	expect(4);

	var el = $( "#slider1" )
		.slider({
			values: [ 0, 0, 0 ],
			start: function( event, ui ) {
				equal(handles.index(ui.handle), 2, "rightmost handle activated when overlapping at minimum (#3736)");
			}
		}),
		handles = el.find( ".ui-slider-handle" );
	handles.eq(0).simulate( "drag", { dx: 10 } );

	QUnit.reset();
	el = $( "#slider1" )
		.slider({
			values: [ 10, 10, 10 ],
			max: 10,
			start: function( event, ui ) {
				equal(handles.index(ui.handle), 0, "leftmost handle activated when overlapping at maximum");
			}
		}),
		handles = el.find( ".ui-slider-handle" );
	handles.eq(0).simulate( "drag", { dx: -10 } );

	QUnit.reset();
	el = $( "#slider1" )
		.slider({
			values: [ 19, 20 ]
		}),
		handles = el.find( ".ui-slider-handle" );
	handles.eq(0).simulate( "drag", { dx: 10 } );
	el.on("slidestart", function(event, ui) {
		equal(handles.index(ui.handle), 0, "left handle activated if left was moved last");
	});
	handles.eq(0).simulate( "drag", { dx: 10 } );

	QUnit.reset();
	el = $( "#slider1" )
		.slider({
			values: [ 19, 20 ]
		}),
		handles = el.find( ".ui-slider-handle" );
	handles.eq(1).simulate( "drag", { dx: -10 } );
	el.on("slidestart", function(event, ui) {
		equal(handles.index(ui.handle), 1, "right handle activated if right was moved last (#3467)");
	});
	handles.eq(0).simulate( "drag", { dx: 10 } );

});

}( jQuery ) );
<commit_msg>Slider tests: Don't use QUnit.reset() or on().<commit_after>/*
 * slider_events.js
 */
(function($) {

module( "slider: events" );

//Specs from http://wiki.jqueryui.com/Slider#specs
//"change callback: triggers when the slider has stopped moving and has a new
// value (even if same as previous value), via mouse(mouseup) or keyboard(keyup)
// or value method/option"
test( "mouse based interaction", function() {
	expect(4);

	var el = $( "#slider1" )
		.slider({
			start: function( event ) {
				equal( event.originalEvent.type, "mousedown", "start triggered by mousedown" );
			},
			slide: function( event) {
				equal( event.originalEvent.type, "mousemove", "slider triggered by mousemove" );
			},
			stop: function( event ) {
				equal( event.originalEvent.type, "mouseup", "stop triggered by mouseup" );
			},
			change: function( event ) {
				equal( event.originalEvent.type, "mouseup", "change triggered by mouseup" );
			}
		});

	el.find( ".ui-slider-handle" ).eq( 0 )
		.simulate( "drag", { dx: 10, dy: 10 } );

});
test( "keyboard based interaction", function() {
	expect(3);

	// Test keyup at end of handle slide (keyboard)
	var el = $( "#slider1" )
		.slider({
			start: function( event ) {
				equal( event.originalEvent.type, "keydown", "start triggered by keydown" );
			},
			slide: function() {
				ok( false, "Slider never triggered by keys" );
			},
			stop: function( event ) {
				equal( event.originalEvent.type, "keyup", "stop triggered by keyup" );
			},
			change: function( event ) {
				equal( event.originalEvent.type, "keyup", "change triggered by keyup" );
			}
		});

	el.find( ".ui-slider-handle" ).eq( 0 )
		.simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } )
		.simulate( "keypress", { keyCode: $.ui.keyCode.LEFT } )
		.simulate( "keyup", { keyCode: $.ui.keyCode.LEFT } );

});
test( "programmatic event triggers", function() {
	expect(6);

	// Test value method
	var el = $( "

" )
		.slider({
			change: function() {
				ok( true, "change triggered by value method" );
			}
		})
		.slider( "value", 0 );

	// Test values method
	el = $( "

" )
		.slider({
			values: [ 10, 20 ],
			change: function() {
				ok( true, "change triggered by values method" );
			}
		})
		.slider( "values", [80, 90] );

	// Test value option
	el = $( "

" )
		.slider({
			change: function() {
				ok( true, "change triggered by value option" );
			}
		})
		.slider( "option", "value", 0 );

	// Test values option
	el = $( "

" )
		.slider({
			values: [ 10, 20 ],
			change: function() {
				ok( true, "change triggered by values option" );
			}
		})
		.slider( "option", "values", [80, 90] );

});

test( "mouse based interaction part two: when handles overlap", function() {
	expect(4);

	var el = $( "#slider1" )
		.slider({
			values: [ 0, 0, 0 ],
			start: function( event, ui ) {
				equal(handles.index(ui.handle), 2, "rightmost handle activated when overlapping at minimum (#3736)");
			}
		}),
		handles = el.find( ".ui-slider-handle" );
	handles.eq(0).simulate( "drag", { dx: 10 } );
	el.slider( "destroy" );

	el = $( "#slider1" )
		.slider({
			values: [ 10, 10, 10 ],
			max: 10,
			start: function( event, ui ) {
				equal(handles.index(ui.handle), 0, "leftmost handle activated when overlapping at maximum");
			}
		}),
		handles = el.find( ".ui-slider-handle" );
	handles.eq(0).simulate( "drag", { dx: -10 } );
	el.slider( "destroy" );

	el = $( "#slider1" )
		.slider({
			values: [ 19, 20 ]
		}),
		handles = el.find( ".ui-slider-handle" );
	handles.eq(0).simulate( "drag", { dx: 10 } );
	el.one("slidestart", function(event, ui) {
		equal(handles.index(ui.handle), 0, "left handle activated if left was moved last");
	});
	handles.eq(0).simulate( "drag", { dx: 10 } );
	el.slider( "destroy" );

	el = $( "#slider1" )
		.slider({
			values: [ 19, 20 ]
		}),
		handles = el.find( ".ui-slider-handle" );
	handles.eq(1).simulate( "drag", { dx: -10 } );
	el.one("slidestart", function(event, ui) {
		equal(handles.index(ui.handle), 1, "right handle activated if right was moved last (#3467)");
	});
	handles.eq(0).simulate( "drag", { dx: 10 } );

});

}( jQuery ) );
<|endoftext|>


<commit_before>/**
 * ngAuth 0.0.1
 * (c) 2014 Sahat Yalkabov <sahat@me.com>
 * License: MIT
 */

(function(window, angular, undefined) {
  'use strict';

  var config = {
    logoutRedirect: '/',
    loginRedirect: '/',
    loginUrl: '/auth/login',
    signupUrl: '/auth/signup',
    signupRedirect: '/login',
    userObject: 'currentUser',
    loginRoute: '/login',
    signupRoute: '/signup'
  };

  config.providers = {
    google: {
      url: '/auth/google',
      authorizationEndpoint: 'https://accounts.google.com/o/oauth2/auth',
      redirectUri: window.location.origin,
      scope: 'openid profile email',
      requiredUrlParams: ['scope'],
      optionalUrlParams: ['display'],
      display: 'popup',
      protocol: 'OAuth2',
      popupOptions: {
        width: 452,
        height: 633
      }
    },
    facebook: {
      url: '/auth/facebook',
      authorizationEndpoint: 'https://www.facebook.com/dialog/oauth',
      redirectUri: window.location.origin,
      scope: 'email',
      requiredUrlParams: ['display'],
      display: 'popup',
      protocol: 'OAuth2',
      popupOptions: {
        width: 481,
        height: 269
      }
    },
    linkedin: {
      url: '/auth/linkedin',
      authorizationEndpoint: 'https://www.linkedin.com/uas/oauth2/authorization',
      redirectUri: window.location.origin,
      requiredUrlParams: ['state'],
      state: 'STATE',
      protocol: 'OAuth2'
    },
    twitter: {
      url: '/auth/twitter',
      authorizationEndpoint: 'https://api.twitter.com/oauth/authenticate',
      protocol: 'OAuth1'
    }
  };

  angular.module('ngAuth', []).provider('$auth', function() {

    this.logoutRedirect = function(route) {
      if (!route) throw new Error('Enter a valid logout redirect route.');
      config.logoutRedirect = route;
      return this;
    };

    this.loginRedirect = function(route) {
      if (!route) throw new Error('Enter a valid login redirect route.');
      config.loginRedirect = route;
      return this;
    };

    this.signupRedirect = function(route) {
      if (!route) throw new Error('Enter a valid signup redirect route.');
      config.signupRedirect = route;
      return this;
    };

    this.loginUrl = function(url) {
      if (!url) throw new Error('Enter a valid login url.');
      config.loginUrl = url;
      return this;
    };

    this.signupUrl = function(url) {
      if (!url) throw new Error('Enter a valid signup url.');
      config.signupUrl = url;
      return this;
    };

    this.userObject = function(name) {
      if (!name) throw new Error('Enter a valid user object name.');
      config.userObject = name;
      return this;
    };

    this.loginRoute = function(route) {
      if (!url) throw new Error('Enter a valid login route.');
      config.loginRoute = route;
      return this;
    };

    this.signupRoute = function(route) {
      config.signupRoute = route;
      return this;
    };

    this.setProvider = function(params) {
      config.providers[params.name] = config.providers[params.name] || { };
      angular.extend(config.providers[params.name], params);
      return this;
    };

    this.addProvider = function(params) {
      return this;
    };

    this.$get = function($interval, $http, $location, $rootScope, $q, $window) {

      // **Popup** class. The *popup* property refers to the `window` object
      // of the browser popup and the *polling* property is an interval object
      // assigned by the `Popup.prototype.pollPopup` method.
      var Popup = function() {
        this.popup = null;
        this.polling = null;
      };

      // Opens the popup with the optional `options` object to specify width and
      // height of a popup. An event listener is then added to the parent window
      // to wait for the `message` event from the popup. Meanwhile popup is
      // polled to detect when popup is abruptly closed by the user. Returns
      // promise that is either **rejected** in the `pollPopup` or **resolved**
      // in the `postMessageHandler`.
      Popup.prototype.open = function(url, options) {
        var deferred = $q.defer();
        var optionsString = stringifyOptions(prepareOptions(options || { }));

        this.popup = $window.open(url, 'ngAuth', optionsString);
        this.popup.focus();

        this.postMessageHandler(deferred);
        this.pollPopup(deferred);

        return deferred.promise;
      };

      // Polls the popup every 35 milliseconds. If popup is closed by the user
      // intervall polling is cancelled and promise is rejected.
      Popup.prototype.pollPopup = function(deferred) {
        this.polling = $interval(function() {
          if (this.popup.closed) {
            $interval.cancel(this.polling);
            deferred.reject('Popup was closed by the user.');
          }
        }.bind(this), 35);
      };

      Popup.prototype.postMessageHandler = function(deferred) {
        $window.addEventListener('message', function(event) {
          if (event.origin === $window.location.origin) {
            deferred.resolve(event.data);
          }
        }.bind(this), false);
      };

      Popup.prototype.close = function() {
        if (this.popup) {
          this.popup.close();
          this.popup = null;
        }
      };

      function prepareOptions(options) {
        var width = options.width || 500;
        var height = options.height || 500;
        return angular.extend({
          left: ((window.screen.width / 2) - (width / 2)),
          top: ((window.screen.height / 2) - (height / 2)),
          width: width,
          height: height
        }, options);
      }

      function stringifyOptions(options) {
        var optionsStrings = [];
        for (var key in options) {
          if (options.hasOwnProperty(key)) {
            var value;
            switch (options[key]) {
              case true:
                value = '1';
                break;
              case false:
                value = '0';
                break;
              default:
                value = options[key];
            }
            optionsStrings.push(
                key + '=' + value
            );
          }
        }
        return optionsStrings.join(',');
      }

      /**
       * OAuth 1.0
       */
      var OAuth1 = function(config) {
        angular.extend(this, config);
        this.name = config.name;
        this.url = config.url;
        this.authorizationEndpoint = config.authorizationEndpoint;
        this.popupOptions = config.popupOptions;
      };

      OAuth1.prototype.tokenRequest = function() {
        return $http.post(this.url)
      };

      OAuth1.prototype.open = function() {
        var deferred = $q.defer();

        var popup = new Popup();
        popup.open(this.url).then(function(oauthData) {
          this.exchangeForToken(oauthData).then(function(response) {
            deferred.resolve(response.data);
          });
        }.bind(this));

        return deferred.promise;
      };

      OAuth1.prototype.exchangeForToken = function(oauthData) {
        return $http.get(this.url, { params: oauthData });
      };

      /**
       * OAuth 2.0
       */
      var OAuth2 = function(config) {
        angular.extend(this, config); // TODO: define all possible properties, then no need to extend
        this.name = config.name;
        this.clientId = config.clientId;
        this.scope = config.scope;
        this.authorizationEndpoint = config.authorizationEndpoint;
        this.redirectUri = config.redirectUri;
        this.responseType = 'code';
        this.defaultUrlParams = ['response_type', 'client_id', 'redirect_uri'];
        this.requiredUrlParams = config.requiredUrlParams;
        this.optionalUrlParams = config.optionalUrlParams;
        this.popupOptions = config.popupOptions;
      };

      OAuth2.prototype.open = function() {
        var deferred = $q.defer();
        var url = this.buildUrl();
        var popup = new Popup();

        popup.open(url, this.popupOptions).then(function(oauthData) {
          this.exchangeForToken(oauthData).then(function(response) {
            deferred.resolve(response.data);
          });
        }.bind(this));

        return deferred.promise;
      };

      OAuth2.prototype.exchangeForToken = function(oauthData) {
        return $http.post(this.url, {
          code: oauthData.code,
          clientId: this.clientId,
          redirectUri: this.redirectUri
        });
      };

      OAuth2.prototype.buildUrl = function() {
        var baseUrl = this.authorizationEndpoint;
        var qs = this.buildQueryString();
        return [baseUrl, qs].join('?');
      };

      OAuth2.prototype.buildQueryString = function() {
        var obj = this;
        var keyValuePairs = [];

        angular.forEach(this.defaultUrlParams, function(paramName) {
          var camelizedName = camelCase(paramName);
          var paramValue = obj[camelizedName];
          keyValuePairs.push([paramName, encodeURIComponent(paramValue)]);
        });

        angular.forEach(this.requiredUrlParams, function(paramName) {
          var camelizedName = camelCase(paramName);
          var paramValue = obj[camelizedName];
          keyValuePairs.push([paramName, encodeURIComponent(paramValue)]);
        });

        angular.forEach(this.optionalUrlParams, function(paramName) {
          var camelizedName = camelCase(paramName);
          var paramValue = obj[camelizedName];
          keyValuePairs.push([paramName, encodeURIComponent(paramValue)]);
        });

        return keyValuePairs.map(function(pair) {
          return pair.join('=');
        }).join('&');
      };

      // loginWithUsername
      // loginWithOauth withThirdParty
      return {
        authenticate: function(providerName, options) {
          if (!providerName) {
            return $q.reject('Expected a provider named \'' + providerName + '\', did you forget to add it?');
          }

          if (config.providers[providerName].protocol === 'OAuth1') {
            var provider;
            provider = new OAuth1(config.providers[providerName]);
          } else {

            provider = new OAuth2(config.providers[providerName]);
          }

          var deferred = $q.defer();

          provider.open(options).then(function(token) {
            var payload = JSON.parse($window.atob(token.split('.')[1]));
            $window.localStorage.token = token;
            $rootScope.currentUser = payload.user;
            $location.path(config.loginRedirect);
            deferred.resolve();
          });

          return deferred.promise;
        },

        login: function(user) {
          if (!user) throw new Error('User object cannot be undefined.')
          var deferred = $q.defer();

          $http.post(config.loginUrl, user)
            .success(function(data) {
              $window.localStorage.token = data.token;
              var payload = JSON.parse($window.atob(data.token.split('.')[1]));
              $rootScope.currentUser = payload.user;
              $location.path(config.loginRedirect);
              deferred.resolve();
            })
            .error(function(error) {
              deferred.reject(error);
            });

          return deferred.promise;
        },
        signup: function(user) {
          return $http.post(config.signupUrl, user).success(function() {
            $location.path(config.signupRedirect);
          });
        },
        logout: function() {
          delete $window.localStorage.token;
          $rootScope.currentUser = null;
          $location.path(config.logoutRedirect);
        },
        isAuthenticated: function() {
          return Boolean($rootScope.currentUser);
        }
      };
    };

  })
    .factory('authInterceptor', function($q, $window, $location) {
      return {
        request: function(config) {
          if ($window.localStorage.token) {
            config.headers.Authorization = 'Bearer ' + $window.localStorage.token;
          }
          return config;
        },
        responseError: function(response) {
          if (response.status === 401 || response.status === 403) {
            $location.path('/login');
          }
          return $q.reject(response);
        }
      }
    })
    .config(function($httpProvider) {
      $httpProvider.interceptors.push('authInterceptor');
    })
    .run(function($rootScope, $window, $location) {
      var token = $window.localStorage.token;
      if (token) {
        var payload = JSON.parse($window.atob(token.split('.')[1]));
        $rootScope.currentUser = payload.user;
      }

      var params = $window.location.search.substring(1);
      var qs = parseQueryString(params);
      if ($window.opener && $window.opener.location.origin === $window.location.origin) {
        if (qs.oauth_token && qs.oauth_verifier) {
          $window.opener.postMessage({ oauth_token: qs.oauth_token, oauth_verifier: qs.oauth_verifier }, '*');
        } else if (qs.code) {
          $window.opener.postMessage({ code: qs.code }, '*');
        }
        $window.close();
      }

      $rootScope.$on('$routeChangeStart', function(event, current, previous) {
        if ($rootScope.currentUser &&
          (current.originalPath === '/login' || current.originalPath === '/signup')) {
          $location.path('/');
        }
        if (current.authenticated && !$rootScope.currentUser) {
          $location.path('/login');
        }
      });
    });

  function parseQueryString(keyValue) {
    var obj = { }, key, value;
    angular.forEach((keyValue || '').split('&'), function(keyValue) {
      if (keyValue) {
        value = keyValue.split('=');
        key = decodeURIComponent(value[0]);
        obj[key] = angular.isDefined(value[1]) ? decodeURIComponent(value[1]) : true;
      }
    });
    return obj;
  }

  function camelCase(name) {
    return name.replace(/([\:\-\_]+(.))/g, function(_, separator, letter, offset) {
      return offset ? letter.toUpperCase() : letter;
    });
  }
})(window, window.angular);

<commit_msg>test if setProvider is defined in config object of ngAuth<commit_after>/**
 * ngAuth 0.0.1
 * (c) 2014 Sahat Yalkabov <sahat@me.com>
 * License: MIT
 */

/**
 * $facebook.config(property) - Return the config property.
 $facebook.getAuthResponse() - Return the AuthResponse(assuming you already connected)
 $facebook.getLoginStatus() - Return promise of the result.
 $facebook.login() - Logged in to your app by facebook. Return promise of the result.
 $facebook.logout() - Logged out from facebook. Return promise of the result.
 $facebook.ui(params) - Do UI action(see facebook sdk docs). Return promise of the result.
 $facebook.api(args...) - Do API action(see facebook sdk docs). Return promise of the result.
 $facebook.cachedApi(args...) - Do API action(see above), but the result will cached. Return promise of the result.
 */

/*
 The service will broadcast the facebook sdk events with the prefix fb..

 In return you will get the next arguments to your $on handler: event,response,FB (FB is the facebook native js sdk).

 fb.auth.login
 fb.auth.logout
 fb.auth.prompt
 fb.auth.sessionChange
 fb.auth.statusChange
 fb.auth.authResponseChange
 fb.xfbml.render
 fb.edge.create
 fb.edge.remove
 fb.comment.create
 fb.comment.remove
 fb.message.send
 */

(function(window, angular, undefined) {
  'use strict';

  var config = {
    logoutRedirect: '/',
    loginRedirect: '/',
    loginUrl: '/auth/login',
    signupUrl: '/auth/signup',
    signupRedirect: '/login',
    userObject: 'currentUser',
    loginRoute: '/login',
    signupRoute: '/signup'
  };

  config.providers = {
    google: {
      url: '/auth/google',
      authorizationEndpoint: 'https://accounts.google.com/o/oauth2/auth',
      redirectUri: window.location.origin,
      scope: 'openid profile email',
      requiredUrlParams: ['scope'],
      optionalUrlParams: ['display'],
      display: 'popup',
      protocol: 'OAuth2',
      popupOptions: {
        width: 452,
        height: 633
      }
    },
    facebook: {
      url: '/auth/facebook',
      authorizationEndpoint: 'https://www.facebook.com/dialog/oauth',
      redirectUri: window.location.origin,
      scope: 'email',
      requiredUrlParams: ['display'],
      display: 'popup',
      protocol: 'OAuth2',
      popupOptions: {
        width: 481,
        height: 269
      }
    },
    linkedin: {
      url: '/auth/linkedin',
      authorizationEndpoint: 'https://www.linkedin.com/uas/oauth2/authorization',
      redirectUri: window.location.origin,
      requiredUrlParams: ['state'],
      state: 'STATE',
      protocol: 'OAuth2'
    },
    twitter: {
      url: '/auth/twitter',
      authorizationEndpoint: 'https://api.twitter.com/oauth/authenticate',
      protocol: 'OAuth1'
    }
  };

  angular.module('ngAuth', []).provider('$auth', function() {

    this.logoutRedirect = function(route) {
      if (!route) throw new Error('Enter a valid logout redirect route.');
      config.logoutRedirect = route;
      return this;
    };

    this.loginRedirect = function(route) {
      if (!route) throw new Error('Enter a valid login redirect route.');
      config.loginRedirect = route;
      return this;
    };

    this.signupRedirect = function(route) {
      if (!route) throw new Error('Enter a valid signup redirect route.');
      config.signupRedirect = route;
      return this;
    };

    this.loginUrl = function(url) {
      if (!url) throw new Error('Enter a valid login url.');
      config.loginUrl = url;
      return this;
    };

    this.signupUrl = function(url) {
      if (!url) throw new Error('Enter a valid signup url.');
      config.signupUrl = url;
      return this;
    };

    this.userObject = function(name) {
      if (!name) throw new Error('Enter a valid user object name.');
      config.userObject = name;
      return this;
    };

    this.loginRoute = function(route) {
      if (!url) throw new Error('Enter a valid login route.');
      config.loginRoute = route;
      return this;
    };

    this.signupRoute = function(route) {
      config.signupRoute = route;
      return this;
    };

    this.setProvider = function(params) {
      config.providers[params.name] = config.providers[params.name] || { };
      angular.extend(config.providers[params.name], params);
      return this;
    };

    this.addProvider = function(params) {
      return this;
    };

    this.$get = function($interval, $http, $location, $rootScope, $q, $window) {

      // **Popup** class. The *popup* property refers to the `window` object
      // of the browser popup and the *polling* property is an interval object
      // assigned by the `Popup.prototype.pollPopup` method.
      var Popup = function() {
        this.popup = null;
        this.polling = null;
      };

      // Opens the popup with the optional `options` object to specify width and
      // height of a popup. An event listener is then added to the parent window
      // to wait for the `message` event from the popup. Meanwhile popup is
      // polled to detect when popup is abruptly closed by the user. Returns
      // promise that is either **rejected** in the `pollPopup` or **resolved**
      // in the `postMessageHandler`.
      Popup.prototype.open = function(url, options) {
        var deferred = $q.defer();
        var optionsString = stringifyOptions(prepareOptions(options || { }));

        this.popup = $window.open(url, 'ngAuth', optionsString);
        this.popup.focus();

        this.postMessageHandler(deferred);
        this.pollPopup(deferred);

        return deferred.promise;
      };

      // Polls the popup every 35 milliseconds. If popup is closed by the user
      // intervall polling is cancelled and promise is rejected.
      Popup.prototype.pollPopup = function(deferred) {
        this.polling = $interval(function() {
          if (this.popup.closed) {
            $interval.cancel(this.polling);
            deferred.reject('Popup was closed by the user.');
          }
        }.bind(this), 35);
      };

      Popup.prototype.postMessageHandler = function(deferred) {
        $window.addEventListener('message', function(event) {
          if (event.origin === $window.location.origin) {
            deferred.resolve(event.data);
          }
        }.bind(this), false);
      };

      Popup.prototype.close = function() {
        if (this.popup) {
          this.popup.close();
          this.popup = null;
        }
      };

      function prepareOptions(options) {
        var width = options.width || 500;
        var height = options.height || 500;
        return angular.extend({
          left: ((window.screen.width / 2) - (width / 2)),
          top: ((window.screen.height / 2) - (height / 2)),
          width: width,
          height: height
        }, options);
      }

      function stringifyOptions(options) {
        var optionsStrings = [];
        for (var key in options) {
          if (options.hasOwnProperty(key)) {
            var value;
            switch (options[key]) {
              case true:
                value = '1';
                break;
              case false:
                value = '0';
                break;
              default:
                value = options[key];
            }
            optionsStrings.push(
                key + '=' + value
            );
          }
        }
        return optionsStrings.join(',');
      }

      /**
       * OAuth 1.0
       */
      var OAuth1 = function(config) {
        angular.extend(this, config);
        this.name = config.name;
        this.url = config.url;
        this.authorizationEndpoint = config.authorizationEndpoint;
        this.popupOptions = config.popupOptions;
      };

      OAuth1.prototype.tokenRequest = function() {
        return $http.post(this.url)
      };

      OAuth1.prototype.open = function() {
        var deferred = $q.defer();

        var popup = new Popup();
        popup.open(this.url).then(function(oauthData) {
          this.exchangeForToken(oauthData).then(function(response) {
            deferred.resolve(response.data);
          });
        }.bind(this));

        return deferred.promise;
      };

      OAuth1.prototype.exchangeForToken = function(oauthData) {
        return $http.get(this.url, { params: oauthData });
      };

      /**
       * OAuth 2.0
       */
      var OAuth2 = function(config) {
        angular.extend(this, config); // TODO: define all possible properties, then no need to extend
        this.name = config.name;
        this.clientId = config.clientId;
        this.scope = config.scope;
        this.authorizationEndpoint = config.authorizationEndpoint;
        this.redirectUri = config.redirectUri;
        this.responseType = 'code';
        this.defaultUrlParams = ['response_type', 'client_id', 'redirect_uri'];
        this.requiredUrlParams = config.requiredUrlParams;
        this.optionalUrlParams = config.optionalUrlParams;
        this.popupOptions = config.popupOptions;
      };

      OAuth2.prototype.open = function() {
        var deferred = $q.defer();
        var url = this.buildUrl();
        var popup = new Popup();

        popup.open(url, this.popupOptions).then(function(oauthData) {
          this.exchangeForToken(oauthData).then(function(response) {
            deferred.resolve(response.data);
          });
        }.bind(this));

        return deferred.promise;
      };

      OAuth2.prototype.exchangeForToken = function(oauthData) {
        return $http.post(this.url, {
          code: oauthData.code,
          clientId: this.clientId,
          redirectUri: this.redirectUri
        });
      };

      OAuth2.prototype.buildUrl = function() {
        var baseUrl = this.authorizationEndpoint;
        var qs = this.buildQueryString();
        return [baseUrl, qs].join('?');
      };

      OAuth2.prototype.buildQueryString = function() {
        var obj = this;
        var keyValuePairs = [];

        angular.forEach(this.defaultUrlParams, function(paramName) {
          var camelizedName = camelCase(paramName);
          var paramValue = obj[camelizedName];
          keyValuePairs.push([paramName, encodeURIComponent(paramValue)]);
        });

        angular.forEach(this.requiredUrlParams, function(paramName) {
          var camelizedName = camelCase(paramName);
          var paramValue = obj[camelizedName];
          keyValuePairs.push([paramName, encodeURIComponent(paramValue)]);
        });

        angular.forEach(this.optionalUrlParams, function(paramName) {
          var camelizedName = camelCase(paramName);
          var paramValue = obj[camelizedName];
          keyValuePairs.push([paramName, encodeURIComponent(paramValue)]);
        });

        return keyValuePairs.map(function(pair) {
          return pair.join('=');
        }).join('&');
      };

      // loginWithUsername
      // loginWithOauth withThirdParty
      return {
        authenticate: function(providerName, options) {
          if (!providerName) {
            return $q.reject('Expected a provider named \'' + providerName + '\', did you forget to add it?');
          }

          if (config.providers[providerName].protocol === 'OAuth1') {
            var provider;
            provider = new OAuth1(config.providers[providerName]);
          } else {

            provider = new OAuth2(config.providers[providerName]);
          }

          var deferred = $q.defer();

          provider.open(options).then(function(token) {
            var payload = JSON.parse($window.atob(token.split('.')[1]));
            $window.localStorage.token = token;
            $rootScope.currentUser = payload.user;
            $location.path(config.loginRedirect);
            deferred.resolve();
          });

          return deferred.promise;
        },

        login: function(user) {
          if (!user) throw new Error('Must take a user object.')
          var deferred = $q.defer();
          $http.post(config.loginUrl, user)
            .success(function(data) {
              $window.localStorage.token = data.token;
              var payload = JSON.parse($window.atob(data.token.split('.')[1]));
              $rootScope.currentUser = payload.user;
              $location.path(config.loginRedirect);
              deferred.resolve(payload.user);
            })
            .error(function(error) {
              deferred.reject(error);
            });
          return deferred.promise;
        },
        signup: function(user) {
          return $http.post(config.signupUrl, user).success(function() {
            $location.path(config.signupRedirect);
          });
        },
        logout: function() {
          delete $window.localStorage.token;
          $rootScope.currentUser = null;
          $location.path(config.logoutRedirect);
        },
        isAuthenticated: function() {
          return Boolean($rootScope.currentUser);
        }
      };
    };

  })
    .factory('authInterceptor', function($q, $window, $location) {
      return {
        request: function(config) {
          if ($window.localStorage.token) {
            config.headers.Authorization = 'Bearer ' + $window.localStorage.token;
          }
          return config;
        },
        responseError: function(response) {
          if (response.status === 401 || response.status === 403) {
            $location.path('/login');
          }
          return $q.reject(response);
        }
      }
    })
    .config(function($httpProvider) {
      $httpProvider.interceptors.push('authInterceptor');
    })
    .run(function($rootScope, $window, $location) {
      var token = $window.localStorage.token;
      if (token) {
        var payload = JSON.parse($window.atob(token.split('.')[1]));
        $rootScope.currentUser = payload.user;
      }

      var params = $window.location.search.substring(1);
      var qs = parseQueryString(params);
      if ($window.opener && $window.opener.location.origin === $window.location.origin) {
        if (qs.oauth_token && qs.oauth_verifier) {
          $window.opener.postMessage({ oauth_token: qs.oauth_token, oauth_verifier: qs.oauth_verifier }, '*');
        } else if (qs.code) {
          $window.opener.postMessage({ code: qs.code }, '*');
        }
        $window.close();
      }

      $rootScope.$on('$routeChangeStart', function(event, current, previous) {
        if ($rootScope.currentUser &&
          (current.originalPath === '/login' || current.originalPath === '/signup')) {
          $location.path('/');
        }
        if (current.authenticated && !$rootScope.currentUser) {
          $location.path('/login');
        }
      });
    });

  function parseQueryString(keyValue) {
    var obj = { }, key, value;
    angular.forEach((keyValue || '').split('&'), function(keyValue) {
      if (keyValue) {
        value = keyValue.split('=');
        key = decodeURIComponent(value[0]);
        obj[key] = angular.isDefined(value[1]) ? decodeURIComponent(value[1]) : true;
      }
    });
    return obj;
  }

  function camelCase(name) {
    return name.replace(/([\:\-\_]+(.))/g, function(_, separator, letter, offset) {
      return offset ? letter.toUpperCase() : letter;
    });
  }
})(window, window.angular);

<|endoftext|>


<commit_before>/*!
 * de-pre.js v0.0.1 2014-08-12T22:10:24
 * https://github.com/neogeek/de-pre.js
 *
 * Copyright (c) 2014 Scott Doxey
 * Released under the MIT license.
 */
!function(a,b){"use strict";"function"==typeof define&&void 0!==define.amd?define([],b):a.depre=b}(this,function(a){"use strict";Array.prototype.slice.call(document.querySelectorAll(a)).forEach(function(a){var b=a.previousSibling.nodeValue.match(/([ \t]*)$/),c=a.innerText;c=c.replace(new RegExp("(^|\n)"+b[1],"g"),"$1"),c=c.replace(/^\s+|\s+$/g,""),a.innerText=c})});<commit_msg>Removed minified file.<commit_after><|endoftext|>


<commit_before>/**
 * ngAuth 0.0.1
 * (c) 2014 Sahat Yalkabov <sahat@me.com>
 * License: MIT
 */

/**
 * $facebook.config(property) - Return the config property.
 $facebook.getAuthResponse() - Return the AuthResponse(assuming you already connected)
 $facebook.getLoginStatus() - Return promise of the result.
 $facebook.login() - Logged in to your app by facebook. Return promise of the result.
 $facebook.logout() - Logged out from facebook. Return promise of the result.
 $facebook.ui(params) - Do UI action(see facebook sdk docs). Return promise of the result.
 $facebook.api(args...) - Do API action(see facebook sdk docs). Return promise of the result.
 $facebook.cachedApi(args...) - Do API action(see above), but the result will cached. Return promise of the result.
 */

/*
 The service will broadcast the facebook sdk events with the prefix fb..

 In return you will get the next arguments to your $on handler: event,response,FB (FB is the facebook native js sdk).

 fb.auth.login
 fb.auth.logout
 fb.auth.prompt
 fb.auth.sessionChange
 fb.auth.statusChange
 fb.auth.authResponseChange
 fb.xfbml.render
 fb.edge.create
 fb.edge.remove
 fb.comment.create
 fb.comment.remove
 fb.message.send
 */

(function(window, angular, undefined) {
  'use strict';

  var config = {
    logoutRedirect: '/',
    loginRedirect: '/',
    loginUrl: '/auth/login',
    signupUrl: '/auth/signup',
    signupRedirect: '/login',
    loginRoute: '/login',
    signupRoute: '/signup',
    user: 'currentUser'
  };

  var providers = {
    google: {
      url: '/auth/google',
      authorizationEndpoint: 'https://accounts.google.com/o/oauth2/auth',
      redirectUri: window.location.origin,
      scope: 'openid profile email',
      requiredUrlParams: ['scope'],
      optionalUrlParams: ['display'],
      display: 'popup',
      type: 'OAuth2',
      popupOptions: {
        width: 452,
        height: 633
      }
    },
    facebook: {
      url: '/auth/facebook',
      authorizationEndpoint: 'https://www.facebook.com/dialog/oauth',
      redirectUri: window.location.origin,
      scope: 'email',
      requiredUrlParams: ['display'],
      display: 'popup',
      type: 'OAuth2',
      popupOptions: {
        width: 481,
        height: 269
      }
    },
    linkedin: {
      url: '/auth/linkedin',
      authorizationEndpoint: 'https://www.linkedin.com/uas/oauth2/authorization',
      redirectUri: window.location.origin,
      requiredUrlParams: ['state'],
      state: 'STATE',
      type: 'OAuth2'
    },
    twitter: {
      url: '/auth/twitter',
      authorizationEndpoint: 'https://api.twitter.com/oauth/authenticate',
      type: 'OAuth1'
    }
  };

  angular.module('ngAuth', []).provider('$auth', function() {

    this.config = config;

    // Configure an existing provider by supplying additional information
    // such as scope, clientId, redirectUri.
    this.setProvider = function(params) {
      if (!params.name) {
        throw new Error('You did not set a provider\'s name.');
      }

      if (!providers[params.name]) {
        throw new Error('Provider ' + params.name + ' is not found. Are you trying to add a custom provider? Use addProvider() instead.');
      }

      angular.extend(providers[params.name], params);
    };

    // Add a custom provider by supplying everything that setProvider
    // requires plus additional information like authorizationEndpoint
    // and requiredParameters.
    this.addProvider = function(params) {
      if (!params.name) {
        throw new Error('You did not set a provider\'s name.');
      }

      if (providers[params.name]) {
        throw new Error('Provider ' + params.name + ' already exists. Use setProvider() instead.');
      }

      providers[params.name] = {};
      angular.extend(providers[params.name], params);
    };

    this.$get = function($interval, $http, $location, $rootScope, $q, $window) {

      // **Popup** constructor. The *popup* property refers to the `window`
      // object of the browser popup and the *polling* property is an interval
      // object assigned by the `Popup.prototype.pollPopup` method.
      var Popup = function() {
        this.popup = null;
        this.polling = null;
      };

      // Opens the popup with the optional `options` object to specify width and
      // height of a popup. An event listener is then added to the parent window
      // to wait for the `message` event from the popup. Meanwhile popup is
      // polled to detect when popup is abruptly closed by the user. Returns
      // promise that is either **rejected** in the `pollPopup` or **resolved**
      // in the `postMessageHandler`.
      Popup.prototype.open = function(url, options) {
        var deferred = $q.defer();
        var optionsString = stringifyOptions(prepareOptions(options || { }));

        this.popup = $window.open(url, 'ngAuth', optionsString);
        this.popup.focus();

        this.postMessageHandler(deferred);
        this.pollPopup(deferred);

        return deferred.promise;
      };

      // Polls the popup every 35 milliseconds. If popup is closed by the user
      // intervall polling is cancelled and promise is rejected.
      Popup.prototype.pollPopup = function(deferred) {
        this.polling = $interval(function() {
          if (this.popup.closed) {
            $interval.cancel(this.polling);
            deferred.reject('Popup was closed by the user.');
          }
        }.bind(this), 35);
      };

      // Listens for the *message* event that contains an `authorization_code`
      // string.
      Popup.prototype.postMessageHandler = function(deferred) {
        $window.addEventListener('message', function(event) {
          if (event.origin === $window.location.origin) {
            deferred.resolve(event.data);
          }
        }, false);
      };

      function prepareOptions(options) {
        var width = options.width || 500;
        var height = options.height || 500;
        return angular.extend({
          left: ((window.screen.width / 2) - (width / 2)),
          top: ((window.screen.height / 2) - (height / 2)),
          width: width,
          height: height
        }, options);
      }

      function stringifyOptions(options) {
        var optionsStrings = [];
        for (var key in options) {
          if (options.hasOwnProperty(key)) {
            var value;
            switch (options[key]) {
              case true:
                value = '1';
                break;
              case false:
                value = '0';
                break;
              default:
                value = options[key];
            }
            optionsStrings.push(
                key + '=' + value
            );
          }
        }
        return optionsStrings.join(',');
      }

      /**
       * OAuth 1.0
       */
      var OAuth1 = function(config) {
        angular.extend(this, config);
        this.name = config.name;
        this.url = config.url;
        this.authorizationEndpoint = config.authorizationEndpoint;
        this.popupOptions = config.popupOptions;
      };

      OAuth1.prototype.tokenRequest = function() {
        return $http.post(this.url)
      };

      OAuth1.prototype.open = function() {
        var deferred = $q.defer();

        var popup = new Popup();
        popup.open(this.url).then(function(oauthData) {
          this.exchangeForToken(oauthData).then(function(response) {
            deferred.resolve(response.data);
          });
        }.bind(this));

        return deferred.promise;
      };

      OAuth1.prototype.exchangeForToken = function(oauthData) {
        return $http.get(this.url, { params: oauthData });
      };

      /**
       * OAuth 2.0
       */
      var OAuth2 = function(config) {
        angular.extend(this, config); // TODO: define all possible properties, then no need to extend
        this.name = config.name;
        this.clientId = config.clientId;
        this.scope = config.scope;
        this.authorizationEndpoint = config.authorizationEndpoint;
        this.redirectUri = config.redirectUri;
        this.responseType = 'code';
        this.defaultUrlParams = ['response_type', 'client_id', 'redirect_uri'];
        this.requiredUrlParams = config.requiredUrlParams;
        this.optionalUrlParams = config.optionalUrlParams;
        this.popupOptions = config.popupOptions;
      };

      OAuth2.prototype.open = function() {
        var deferred = $q.defer();
        var url = this.buildUrl();
        var popup = new Popup();

        popup.open(url, this.popupOptions).then(function(oauthData) {
          this.exchangeForToken(oauthData).then(function(response) {
            deferred.resolve(response.data);
          });
        }.bind(this));

        return deferred.promise;
      };

      OAuth2.prototype.exchangeForToken = function(oauthData) {
        return $http.post(this.url, {
          code: oauthData.code,
          clientId: this.clientId,
          redirectUri: this.redirectUri
        });
      };

      OAuth2.prototype.buildUrl = function() {
        var baseUrl = this.authorizationEndpoint;
        var qs = this.buildQueryString();
        return [baseUrl, qs].join('?');
      };

      OAuth2.prototype.buildQueryString = function() {
        var obj = this;
        var keyValuePairs = [];

        angular.forEach(this.defaultUrlParams, function(paramName) {
          var camelizedName = camelCase(paramName);
          var paramValue = obj[camelizedName];
          keyValuePairs.push([paramName, encodeURIComponent(paramValue)]);
        });

        angular.forEach(this.requiredUrlParams, function(paramName) {
          var camelizedName = camelCase(paramName);
          var paramValue = obj[camelizedName];
          keyValuePairs.push([paramName, encodeURIComponent(paramValue)]);
        });

        angular.forEach(this.optionalUrlParams, function(paramName) {
          var camelizedName = camelCase(paramName);
          var paramValue = obj[camelizedName];
          keyValuePairs.push([paramName, encodeURIComponent(paramValue)]);
        });

        return keyValuePairs.map(function(pair) {
          return pair.join('=');
        }).join('&');
      };

      return {
        authenticate: function(providerName, options) {
          if (!providerName) {
            return $q.reject('Expected a provider named \'' + providerName + '\', did you forget to add it?');
          }

          if (providers[providerName].type === 'OAuth1') {
            var provider;
            provider = new OAuth1(providers[providerName]);
          } else {

            provider = new OAuth2(providers[providerName]);
          }

          var deferred = $q.defer();

          provider.open(options).then(function(token) {
            var payload = JSON.parse($window.atob(token.split('.')[1]));
            $window.localStorage.jwtToken = token;
            $rootScope[config.user] = payload.user;
            $location.path(config.loginRedirect);
            deferred.resolve();
          });

          return deferred.promise;
        },

        login: function(user) {
          if (!user) throw new Error('Must take a user object.')
          var deferred = $q.defer();
          $http.post(config.loginUrl, user)
            .success(function(data) {
              $window.localStorage.jwtToken = data.token;
              var payload = JSON.parse($window.atob(data.token.split('.')[1]));
              $rootScope[config.user] = payload.user;
              $location.path(config.loginRedirect);
              deferred.resolve(payload.user);
            })
            .error(function(error) {
              deferred.reject(error);
            });
          return deferred.promise;
        },
        signup: function(user) {
          return $http.post(config.signupUrl, user).success(function() {
            $location.path(config.signupRedirect);
          });
        },
        logout: function() {
          $location.path(config.logoutRedirect);
          delete $rootScope[config.user];
          delete $window.localStorage.jwtToken;
        },
        isAuthenticated: function() {
          return Boolean($rootScope.currentUser);
        }
      };
    };

  })
    .factory('authInterceptor', function($q, $window, $location) {
      return {
        request: function(config) {
          if ($window.localStorage.jwtToken) {
            config.headers.Authorization = 'Bearer ' + $window.localStorage.jwtToken;
          }
          return config;
        },
        responseError: function(response) {
          if (response.status === 401 || response.status === 403) {
            $location.path('/login');
          }
          return $q.reject(response);
        }
      }
    })
    .config(function($httpProvider) {
      $httpProvider.interceptors.push('authInterceptor');
    })
    .run(function($rootScope, $window, $location) {
      var token = $window.localStorage.jwtToken;
      if (token) {
        var payload = JSON.parse($window.atob(token.split('.')[1]));
        $rootScope.currentUser = payload.user;
      }

      var params = $window.location.search.substring(1);
      var qs = parseQueryString(params);
      if ($window.opener && $window.opener.location.origin === $window.location.origin) {
        if (qs.oauth_token && qs.oauth_verifier) {
          $window.opener.postMessage({ oauth_token: qs.oauth_token, oauth_verifier: qs.oauth_verifier }, '*');
        } else if (qs.code) {
          $window.opener.postMessage({ code: qs.code }, '*');
        }
        $window.close();
      }

      $rootScope.$on('$routeChangeStart', function(event, current, previous) {
        if ($rootScope[config.user] &&
          (current.originalPath === '/login' || current.originalPath === '/signup')) {
          $location.path('/');
        }
        if (current.authenticated && !$rootScope[config.user]) {
          $location.path('/login');
        }
      });
    });

  function parseQueryString(keyValue) {
    var obj = { }, key, value;
    angular.forEach((keyValue || '').split('&'), function(keyValue) {
      if (keyValue) {
        value = keyValue.split('=');
        key = decodeURIComponent(value[0]);
        obj[key] = angular.isDefined(value[1]) ? decodeURIComponent(value[1]) : true;
      }
    });
    return obj;
  }

  function camelCase(name) {
    return name.replace(/([\:\-\_]+(.))/g, function(_, separator, letter, offset) {
      return offset ? letter.toUpperCase() : letter;
    });
  }
})(window, window.angular);

<commit_msg>code refactoring<commit_after>/**
 * ngAuth 0.0.1
 * (c) 2014 Sahat Yalkabov <sahat@me.com>
 * License: MIT
 */

(function(window, angular, undefined) {
  'use strict';

  var config = {
    logoutRedirect: '/',
    loginRedirect: '/',
    loginUrl: '/auth/login',
    signupUrl: '/auth/signup',
    signupRedirect: '/login',
    loginRoute: '/login',
    signupRoute: '/signup',
    user: 'currentUser'
  };

  var providers = {
    google: {
      url: '/auth/google',
      authorizationEndpoint: 'https://accounts.google.com/o/oauth2/auth',
      redirectUri: window.location.origin,
      scope: 'openid profile email',
      requiredUrlParams: ['scope'],
      optionalUrlParams: ['display'],
      display: 'popup',
      type: 'oauth2',
      popupOptions: {
        width: 452,
        height: 633
      }
    },
    facebook: {
      url: '/auth/facebook',
      authorizationEndpoint: 'https://www.facebook.com/dialog/oauth',
      redirectUri: window.location.origin,
      scope: 'email',
      requiredUrlParams: ['display'],
      display: 'popup',
      type: 'oauth2',
      popupOptions: {
        width: 481,
        height: 269
      }
    },
    linkedin: {
      url: '/auth/linkedin',
      authorizationEndpoint: 'https://www.linkedin.com/uas/oauth2/authorization',
      redirectUri: window.location.origin,
      requiredUrlParams: ['state'],
      state: 'STATE',
      type: 'oauth2'
    },
    twitter: {
      url: '/auth/twitter',
      authorizationEndpoint: 'https://api.twitter.com/oauth/authenticate',
      type: 'oauth1'
    }
  };

  angular.module('ngAuth', []).provider('$auth', function() {

    this.config = config;

    // Configure an existing provider by supplying additional information
    // such as scope, clientId, redirectUri.
    this.setProvider = function(params) {
      if (!params.name) {
        throw new Error('You did not set a provider\'s name.');
      }

      if (!providers[params.name]) {
        throw new Error('Provider ' + params.name + ' is not found. Are you trying to add a custom provider? Use addProvider() instead.');
      }

      angular.extend(providers[params.name], params);
    };

    // Add a custom provider by supplying everything that setProvider
    // requires plus additional information like authorizationEndpoint
    // and requiredParameters.
    this.addProvider = function(params) {
      if (!params.name) {
        throw new Error('You did not set a provider\'s name.');
      }

      if (providers[params.name]) {
        throw new Error('Provider ' + params.name + ' already exists. Use setProvider() instead.');
      }

      providers[params.name] = {};
      angular.extend(providers[params.name], params);
    };

    this.$get = function($interval, $http, $location, $rootScope, $q, $window) {

      // **Popup** constructor. The *popup* property refers to the `window`
      // object of the browser popup and the *polling* property is an interval
      // object assigned by the `Popup.prototype.pollPopup` method.
      var Popup = function() {
        this.popup = null;
        this.polling = null;
      };

      // Opens the popup with the optional `options` object to specify width and
      // height of a popup. An event listener is then added to the parent window
      // to wait for the `message` event from the popup. Meanwhile popup is
      // polled to detect when popup is abruptly closed by the user. Returns
      // promise that is either **rejected** in the `pollPopup` or **resolved**
      // in the `postMessageHandler`.
      Popup.prototype.open = function(url, options) {
        var deferred = $q.defer();
        var optionsString = stringifyOptions(prepareOptions(options || { }));

        this.popup = $window.open(url, 'ngAuth', optionsString);
        this.popup.focus();

        this.postMessageHandler(deferred);
        this.pollPopup(deferred);

        return deferred.promise;
      };

      // Polls the popup every 35 milliseconds. If popup is closed by the user
      // intervall polling is cancelled and promise is rejected.
      Popup.prototype.pollPopup = function(deferred) {
        this.polling = $interval(function() {
          if (this.popup.closed) {
            $interval.cancel(this.polling);
            deferred.reject('Popup was closed by the user.');
          }
        }.bind(this), 35);
      };

      // Listens for the *message* event that contains an `authorization_code`
      // string.
      Popup.prototype.postMessageHandler = function(deferred) {
        $window.addEventListener('message', function(event) {
          if (event.origin === $window.location.origin) {
            deferred.resolve(event.data);
          }
        }, false);
      };

      function prepareOptions(options) {
        var width = options.width || 500;
        var height = options.height || 500;
        return angular.extend({
          left: ((window.screen.width / 2) - (width / 2)),
          top: ((window.screen.height / 2) - (height / 2)),
          width: width,
          height: height
        }, options);
      }

      function stringifyOptions(options) {
        var optionsStrings = [];
        for (var key in options) {
          if (options.hasOwnProperty(key)) {
            var value;
            switch (options[key]) {
              case true:
                value = '1';
                break;
              case false:
                value = '0';
                break;
              default:
                value = options[key];
            }
            optionsStrings.push(
                key + '=' + value
            );
          }
        }
        return optionsStrings.join(',');
      }

      /**
       * OAuth 1.0
       */
      var OAuth1 = function(config) {
        angular.extend(this, config);
        this.name = config.name;
        this.url = config.url;
        this.authorizationEndpoint = config.authorizationEndpoint;
        this.popupOptions = config.popupOptions;
      };

      OAuth1.prototype.tokenRequest = function() {
        return $http.post(this.url)
      };

      OAuth1.prototype.open = function() {
        var deferred = $q.defer();

        var popup = new Popup();
        popup.open(this.url).then(function(oauthData) {
          this.exchangeForToken(oauthData).then(function(response) {
            deferred.resolve(response.data);
          });
        }.bind(this));

        return deferred.promise;
      };

      OAuth1.prototype.exchangeForToken = function(oauthData) {
        return $http.get(this.url, { params: oauthData });
      };

      /**
       * OAuth 2.0
       */
      var OAuth2 = function(config) {
        angular.extend(this, config);
        this.name = config.name;
        this.clientId = config.clientId;
        this.scope = config.scope;
        this.authorizationEndpoint = config.authorizationEndpoint;
        this.redirectUri = config.redirectUri;
        this.responseType = 'code';
        this.defaultUrlParams = ['response_type', 'client_id', 'redirect_uri'];
        this.requiredUrlParams = config.requiredUrlParams;
        this.optionalUrlParams = config.optionalUrlParams;
        this.popupOptions = config.popupOptions;
      };

      OAuth2.prototype.open = function() {
        var deferred = $q.defer();
        var url = this.buildUrl();
        var popup = new Popup();

        popup.open(url, this.popupOptions).then(function(oauthData) {
          this.exchangeForToken(oauthData).then(function(response) {
            deferred.resolve(response.data);
          });
        }.bind(this));

        return deferred.promise;
      };

      OAuth2.prototype.exchangeForToken = function(oauthData) {
        return $http.post(this.url, {
          code: oauthData.code,
          clientId: this.clientId,
          redirectUri: this.redirectUri
        });
      };

      OAuth2.prototype.buildUrl = function() {
        var baseUrl = this.authorizationEndpoint;
        var qs = this.buildQueryString();
        return [baseUrl, qs].join('?');
      };

      OAuth2.prototype.buildQueryString = function() {
        var obj = this;
        var keyValuePairs = [];

        angular.forEach(this.defaultUrlParams, function(paramName) {
          var camelizedName = camelCase(paramName);
          var paramValue = obj[camelizedName];
          keyValuePairs.push([paramName, encodeURIComponent(paramValue)]);
        });

        angular.forEach(this.requiredUrlParams, function(paramName) {
          var camelizedName = camelCase(paramName);
          var paramValue = obj[camelizedName];
          keyValuePairs.push([paramName, encodeURIComponent(paramValue)]);
        });

        angular.forEach(this.optionalUrlParams, function(paramName) {
          var camelizedName = camelCase(paramName);
          var paramValue = obj[camelizedName];
          keyValuePairs.push([paramName, encodeURIComponent(paramValue)]);
        });

        return keyValuePairs.map(function(pair) {
          return pair.join('=');
        }).join('&');
      };

      return {
        authenticate: function(providerName, options) {
          if (!providerName) {
            return $q.reject('Expected a provider named \'' + providerName + '\'. Did you forget to add it?');
          }

          if (providers[providerName].type === 'oauth1') {
            var provider;
            provider = new OAuth1(providers[providerName]);
          } else {
            provider = new OAuth2(providers[providerName]);
          }

          var deferred = $q.defer();

          provider.open(options).then(function(token) {
            var payload = JSON.parse($window.atob(token.split('.')[1]));
            $window.localStorage.jwtToken = token;
            $rootScope[config.user] = payload.user;
            $location.path(config.loginRedirect);
            deferred.resolve();
          });

          return deferred.promise;
        },

        login: function(user) {
          if (!user) throw new Error('You must provide a user object.');
          var deferred = $q.defer();
          $http.post(config.loginUrl, user)
            .success(function(data) {
              var payload = JSON.parse($window.atob(data.token.split('.')[1]));
              $rootScope[config.user] = payload.user;
              $location.path(config.loginRedirect);
              $window.localStorage.jwtToken = data.token;
              deferred.resolve(payload.user);
            })
            .error(function(error) {
              deferred.reject(error);
            });
          return deferred.promise;
        },
        signup: function(user) {
          $http.post(config.signupUrl, user).then(function() {
            $location.path(config.signupRedirect);
          });
        },
        logout: function() {
          delete $rootScope[config.user];
          delete $window.localStorage.jwtToken;
          $location.path(config.logoutRedirect);
        },
        isAuthenticated: function() {
          return Boolean($rootScope.currentUser);
        }
      };
    };

  })
    .factory('authInterceptor', function($q, $window, $location) {
      return {
        request: function(config) {
          if ($window.localStorage.jwtToken) {
            config.headers.Authorization = 'Bearer ' + $window.localStorage.jwtToken;
          }
          return config;
        },
        responseError: function(response) {
          if (response.status === 401 || response.status === 403) {
            $location.path('/login');
          }
          return $q.reject(response);
        }
      }
    })
    .config(function($httpProvider) {
      $httpProvider.interceptors.push('authInterceptor');
    })
    .run(function($rootScope, $window, $location) {
      var token = $window.localStorage.jwtToken;
      if (token) {
        var payload = JSON.parse($window.atob(token.split('.')[1]));
        $rootScope.currentUser = payload.user;
      }

      var params = $window.location.search.substring(1);
      var qs = parseQueryString(params);
      if ($window.opener && $window.opener.location.origin === $window.location.origin) {
        if (qs.oauth_token && qs.oauth_verifier) {
          $window.opener.postMessage({ oauth_token: qs.oauth_token, oauth_verifier: qs.oauth_verifier }, '*');
        } else if (qs.code) {
          $window.opener.postMessage({ code: qs.code }, '*');
        }
        $window.close();
      }

      $rootScope.$on('$routeChangeStart', function(event, current, previous) {
        if ($rootScope[config.user] &&
          (current.originalPath === '/login' || current.originalPath === '/signup')) {
          $location.path('/');
        }
        if (current.authenticated && !$rootScope[config.user]) {
          $location.path('/login');
        }
      });
    });

  function parseQueryString(keyValue) {
    var obj = { }, key, value;
    angular.forEach((keyValue || '').split('&'), function(keyValue) {
      if (keyValue) {
        value = keyValue.split('=');
        key = decodeURIComponent(value[0]);
        obj[key] = angular.isDefined(value[1]) ? decodeURIComponent(value[1]) : true;
      }
    });
    return obj;
  }

  function camelCase(name) {
    return name.replace(/([\:\-\_]+(.))/g, function(_, separator, letter, offset) {
      return offset ? letter.toUpperCase() : letter;
    });
  }
})(window, window.angular);

<|endoftext|>


<commit_before>// Tests demoserver running at hostName by sending a request to a random route
// (c)2015 Larry Lang

hostName  = process.env.DS_HOST;
spinMax   = process.env.SPINMAX || 9;

var randomNumber = function(lower_bound, upper_bound)
{
    //returns random integer between lower and upper bound
    return Math.round(Math.random()*(upper_bound - lower_bound) + lower_bound);
}

spin = randomNumber(0,spinMax);

switch(spin) {
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
    default:
        urlPath = "/"
        break;
    case 5:
    case 6:
    case 7:
        urlPath = "/other"
        break;
    case 8:
        urlPath = "/about"
        break;
    case 9:
        urlPath = "/bogus"
        break;
}

var http = require('http');   //npm install http

var options =
{
host: hostName,
path: urlPath,
method: 'GET',
port: 8080,
headers: {
    'User-Agent': 'democlient Agent/1.0'
}
};

var callback = function(response) {
    console.log("democlient: HTTP status code " + response.statusCode);
    var str = '';
    //another chunk of data has been received, so append it to `str`
    response.on('data', function (chunk) {
                str += chunk;
                });
    //the whole response has been received, so we just print it out here
    response.on('end', function () {
                // uncomment to send full HTTP response to console
                // console.log(str);
                });
}

http.request(options, callback).end();
<commit_msg>spin stuff<commit_after>// Tests demoserver running at hostName by sending a request to a random route
// (c)2015 Larry Lang

hostName  = process.env.DS_HOST;
spinMax   = process.env.SPINMAX || 9;
spinMin   = process.env.SPINMIN || 0;

var randomNumber = function(lower_bound, upper_bound)
{
    //returns random integer between lower and upper bound
    return Math.round(Math.random()*(upper_bound - lower_bound) + lower_bound);
}

spin = randomNumber(spinMin,spinMax);

switch(spin) {
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
        urlPath = "/"
        break;
    case 7:
        urlPath = "/about"
        break;
    case 8:
        urlPath = "/other"
        break;
    case 9:
        urlPath = "/bogus"
        break;
    default:
        urlPath = "/"
        break;
}

var http = require('http');   //npm install http

var options =
{
host: hostName,
path: urlPath,
method: 'GET',
port: 8080,
headers: {
    'User-Agent': 'democlient Agent/1.0'
}
};

var callback = function(response) {
    console.log("democlient: HTTP status code " + response.statusCode);
    var str = '';
    //another chunk of data has been received, so append it to `str`
    response.on('data', function (chunk) {
                str += chunk;
                });
    //the whole response has been received, so we just print it out here
    response.on('end', function () {
                // uncomment to send full HTTP response to console
                // console.log(str);
                });
}

http.request(options, callback).end();
<|endoftext|>


<commit_before>Ext.define('devilry_extjsextras.ContainerWithEditTitle', {
    extend: 'Ext.container.Container',
    alias: 'widget.containerwithedittitle',

    /**
     * @cfg {String} [cls="containerwithedittitle"]
     * Defaults to ``containerwithedittitle``.
     */
    cls: 'containerwithedittitle',

    /**
     * @cfg {String} title
     */

    /**
     * @cfg {Array|Ext.XTemplate} [titleTag="h4"]
     */
    titleTag: 'h4',

    /**
     * @cfg {String} [titleCls='editablesidebarbox_title bootstrap']
     * The css class of the title box.
     */
    titleCls: 'titlebox bootstrap',

    /**
     * @cfg {String} buttontext (optional)
     * Button text. Defaults to "Edit" (translated).
     */
    buttonText: pgettext('uibutton', 'Edit'),

    /**
     * @cfg {String} [title]
     * The title text.
     */

    /**
     * @cfg {Object} [body]
     * The config for the body element. The container
     * uses anchor layout to lay out the title and the body.
     */

    constructor: function(config) {
        this.mixins.observable.constructor.call(this, config);
        this.addEvents(
            /**
             * @event
             * Fired when the edit-button is clicked.
             * @param box This EditableSidebarBox.
             */
            'edit'
        );
        this.callParent([config]);
    },

    initComponent: function() {
        Ext.apply(this, {
            layout: 'anchor',
            items: [{
                xtype: 'box',
                itemId: 'title',
                anchor: '100%',
                cls: this.titleCls,
                tpl: Ext.String.format([
                    '<{0}>',
                        '{title}',
                        ' ',
                        ' ',
                        '(',
                            this.buttonText,
                        ')',
                    '</{1}>'
                ].join(''), this.titleTag),
                data: {
                    title: this.title,
                    editurl: '#'
                },
                listeners: {
                    scope: this,
                    element: 'el',
                    delegate: 'a.edit_link',
                    click: function(e) {
                        e.preventDefault();
                        this.fireEvent('edit', this);
                    }
                }
            }, this.body]
        });
        this.callParent(arguments);
    },

    updateTitle: function(title, editurl) {
        if(typeof editurl === 'undefined') {
            editurl = '#';
        }
        this.down('#title').update({
            title: title,
            editurl: editurl
        });
    }
});
<commit_msg>devilry_extjsextras...ContainerWithEditTitle: Style edit as button.<commit_after>Ext.define('devilry_extjsextras.ContainerWithEditTitle', {
    extend: 'Ext.container.Container',
    alias: 'widget.containerwithedittitle',

    /**
     * @cfg {String} [cls="containerwithedittitle"]
     * Defaults to ``containerwithedittitle``.
     */
    cls: 'containerwithedittitle',

    /**
     * @cfg {String} title
     */

    /**
     * @cfg {Array|Ext.XTemplate} [titleTag="h4"]
     */
    titleTag: 'h4',

    /**
     * @cfg {String} [titleCls='editablesidebarbox_title bootstrap']
     * The css class of the title box.
     */
    titleCls: 'titlebox bootstrap',

    /**
     * @cfg {String} buttontext (optional)
     * Button text. Defaults to "Edit" (translated).
     */
    buttonText: pgettext('uibutton', 'edit'),

    /**
     * @cfg {String} [buttonSuffix]
     * HTML to suffix to the ``buttonText``. Typicallu used to add an icon after the text.
     */
    //buttonSuffix: '',
    buttonSuffix: '',

    /**
     * @cfg {String} [title]
     * The title text.
     */

    /**
     * @cfg {Object} [body]
     * The config for the body element. The container
     * uses anchor layout to lay out the title and the body.
     */

    constructor: function(config) {
        this.mixins.observable.constructor.call(this, config);
        this.addEvents(
            /**
             * @event
             * Fired when the edit-button is clicked.
             * @param box This EditableSidebarBox.
             */
            'edit'
        );
        this.callParent([config]);
    },

    initComponent: function() {
        Ext.apply(this, {
            layout: 'anchor',
            items: [{
                xtype: 'box',
                itemId: 'title',
                anchor: '100%',
                cls: this.titleCls,
                tpl: Ext.String.format([
                    '<{0}>',
                        '{title}',
                        ' ',
                        '',
                            this.buttonText,
                            this.buttonSuffix,
                        '',
                    '</{1}>'
                ].join(''), this.titleTag),
                data: {
                    title: this.title,
                    editurl: '#'
                },
                listeners: {
                    scope: this,
                    element: 'el',
                    delegate: 'a.edit_link',
                    click: function(e) {
                        e.preventDefault();
                        this.fireEvent('edit', this);
                    }
                }
            }, this.body]
        });
        this.callParent(arguments);
    },

    updateTitle: function(title, editurl) {
        if(typeof editurl === 'undefined') {
            editurl = '#';
        }
        this.down('#title').update({
            title: title,
            editurl: editurl
        });
    }
});
<|endoftext|>