<|start_filename|>i18n/en.json<|end_filename|>
{
  "loadingTitle":                  "Please wait...",
  "close":                         "Close",
  "windowsAuthTitle":              "Windows Authentication",
  "invalid":                       "Invalid",
  "mustMatch":                     "Must match",
  "loginSocialButton":             "Login with {connection:title}",
  "signupSocialButton":            "Signup with {connection:title}",
  "networkError":                  "We could not reach the server.<br/>Please try again.",
  "signin": {
    "title":                       "Log in",
    "action":                      "Access",
    "actionDomain":                "Log in to {domain}",
    "all":                         "Show all",
    "strategyEmailEmpty":          "The email is empty.",
    "strategyEmailInvalid":        "The email is invalid.",
    "strategyDomainInvalid":       "The domain {domain} has not been set up.",
    "signupText":                  "Sign Up",
    "forgotText":                  "Reset password",
    "cancelAction":                "Cancel",
    "emailPlaceholder":            "Email",
    "usernamePlaceholder":         "Username",
    "passwordPlaceholder":         "Password",
    "separatorText":               "or",
    "serverErrorText":             "There was an error processing the login.",
    "returnUserLabel":             "Last time you signed in using...",
    "domainUserLabel":             "You are connected from your corporate network...",
    "wrongEmailPasswordErrorText": "Wrong email or password.",
    "or":                          "... or log in using",
    "loadingMessage":              "Logging In with {connection}...",
    "popupCredentials":            "Enter your credentials in the pop-up window",
    "userClosedPopup":             "Popup window closed. Try again.",
    "userConsentFailed":           "Permissions were not granted. Try again."
  },
  "signup": {
    "description":                 "",
    "title":                       "Sign Up",
    "action":                      "Sign Up",
    "emailPlaceholder":            "Email",
    "usernamePlaceholder":         "Username",
    "passwordPlaceholder":         "<PASSWORD>",
    "cancelAction":                "Cancel",
    "headerText":                  "Please enter your email and password",
    "footerText":                  "",
    "enterpriseEmailWarningText":  "This domain {domain} has been configured for Single Sign On and you can't create an account. Try logging in instead.",
    "serverErrorText":             "There was an error processing the signup.",
    "userExistsErrorText":         "The user already exists.",
    "usernameInUseErrorText":      "The username is already in use.",
    "invalidPassword":             "<PASSWORD>.",
    
    "passwordStrength": {
      "nonEmpty": "Non-empty password required",
      "lengthAtLeast": "At least %d characters in length",
      "shouldContain": "Should contain:",
      "containsAtLeast" : "Contain at least %d of the following %d types of characters:",
      "lowerCase": "Lower case letters (a-z)",
      "upperCase": "Upper case letters (A-Z)",
      "numbers": "Numbers (i.e. 0-9)",
      "specialCharacters" : "Special characters (e.g. !@#$%^&*)",
      "identicalChars": "No more than %d identical characters in a row (e.g., \"%s\" not allowed)"
    }
    
  },
  "reset": {
    "title":                       "Reset Password",
    "action":                      "Send",
    "emailPlaceholder":            "Email",
    "passwordPlaceholder":         "<PASSWORD>",
    "repeatPasswordPlaceholder":   "<PASSWORD>",
    "cancelAction":                "Cancel",
    "successText":                 "We've just sent you an email to reset your password.",
    "enterSamePasswordText":       "Please enter the same password.",
    "headerText":                  "Please enter your email and the new password. We will send you an email to confirm the password change.",
    "serverErrorText":             "There was an error processing the password reset.",
    "userDoesNotExistErrorText":   "User does not exist.",
    "invalidPassword":             "<PASSWORD>."
  }
}


<|start_filename|>test/tests.js<|end_filename|>
/**
 * Mocha config
 */

mocha.timeout(60000);
mocha.ui('bdd');
mocha.reporter('html');
mocha.globals(['jQuery*', '__auth0jp*', 'Auth0*']);

/**
 * Define some support variables
 */

var placeholderSupport = ('placeholder' in document.createElement('input'));
var placeholderSupportPrefix = placeholderSupport ? '' : 'not ';

/**
 * Test Auth0Lock
 */

describe('Auth0Lock', function () {
  var domain =      'abc.auth0.com';
  var clientID =    '123456789';
  var callbackURL = 'http://myapp.com/callback';
  var widget, client, getClientConfiguration;

  beforeEach(function (done) {
    getClientConfiguration = Auth0Lock.prototype.getClientConfiguration;
    Auth0Lock.prototype.getClientConfiguration = function (cb) {
      var $client = {
        id: clientID,
        strategies: [{
          'name': 'facebook',
          'connections': [{ 'name': 'facebook', 'domain': '' }]
        }, {
          'name': 'twitter',
          'connections': [{ 'name': 'twitter', 'domain': '' }]
        }, {
          'name': 'google-oauth2',
          'connections': [{ 'name': 'google-oauth2', 'domain': '' }]
        }, {
          'name': 'adfs',
          'connections': [{ 'name': 'contoso', 'domain': 'contoso.com' }]
        }, {
          'name': 'auth0-adldap',
          'connections': [{ 'name': 'adldap', 'domain': 'litware.com' }]
        }, {
          'name': 'auth0',
          'connections': [
            { 'name': 'dbTest', 'domain': '',
              'showSignup': true, 'showForgot': true },
            { 'name': 'Username-Password-Authentication', 'domain': '' }
          ]
        }, {
          'name': 'google-apps',
          'connections': [
            { 'name': 'google-app1', 'domain': '' },
            { 'name': 'google-app2', 'domain': '' },
            { 'name': 'google-app3', 'domain': '' }
          ]
        }
        ]
      };

      if ('function' === typeof done) {
        cb($client);
      }
    };

    widget = new Auth0Lock(clientID, domain);

    client = widget.$auth0;
    client.getSSOData = function (withAd, callback) {
      callback(null, { sso: false });
    };
    done();
  });

  afterEach(function (done) {
    global.window.location.hash = '';
    global.window.Auth0 = null;
    Auth0Lock.prototype.getClientConfiguration = getClientConfiguration;
    if (widget) {
      widget.hide(done);
    } else {
      $('#a0-lock').remove();
      done();
    }
  });

  it('should setup client with callbackOnLocationHash', function (done) {
    widget
    .once('signin ready', function() {
      expect(client._callbackOnLocationHash).to.be(true);
      done();
    })
    .show({
      responseType: 'token'
    });
  });

  it('should setup client with callbackURL', function (done) {
    widget
    .once('ready', function() {
      expect(client._callbackURL).to.be(callbackURL);
      done();
    })
    .show({
      callbackURL: callbackURL
    });
  });

  it('should setup client to use JSONP', function (done) {
    widget
    .once('ready', function() {
      expect(client._useJSONP).to.be(true);
      done();
    })
    .show({
      forceJSONP: true
    });
  });

  it('should remove widget when user close it', function (done) {
    widget
    .once('ready', function () {
      bean.fire($('#a0-lock a.a0-close')[0], 'click');
    })
    .once('hidden', function () {
      expect($('#a0-lock').length).to.equal(0);
      done();
    })
    .show({
      callbackURL: callbackURL,
      responseType: 'token'
    });
  });

  it('should show only notloggedin view if SSO data is not present', function (done) {
    widget
    .once('ready', function () {
      expect($('#a0-lock .a0-notloggedin')).to.not.be.empty();
      expect($('#a0-lock .a0-loggedin')).to.be.empty();
      expect($('#a0-lock .a0-signup')).to.be.empty();
      expect($('#a0-lock .a0-reset')).to.be.empty();
      done();
    })
    .show({
      callbackURL: callbackURL,
      responseType: 'token'
    });

  });

  it('should show only loggedin view with SSO data (social) if it is present', function (done) {
    client.getSSOData = function (withAd, callback) {
      callback(null, {
        sso: true,
        lastUsedUsername: '<EMAIL>',
        lastUsedConnection: { strategy: 'google-oauth2', name: 'google-oauth2' }
      });
    };

    widget
    .once('ready', function () {
      expect($('#a0-lock .a0-notloggedin')).to.be.empty();
      expect($('#a0-lock .a0-loggedin')).to.not.be.empty();
      expect($('#a0-lock .a0-signup')).to.be.empty();
      expect($('#a0-lock .a0-reset')).to.be.empty();
      expect($('#a0-lock .a0-loggedin .a0-strategy [data-strategy]').attr('title')).to.equal('<EMAIL> (Google)');
      done();
    })
    .show({
      callbackURL: callbackURL,
      responseType: 'token'
    });
  });

  it('should not show loggedin view with SSO data (social) if it is not listed/enabled', function (done) {
    client.getSSOData = function (withAd, callback) {
      callback(null, {
        sso: true,
        lastUsedUsername: '<EMAIL>',
        lastUsedConnection: { strategy: 'google-oauth2', name: 'google-oauth2' }
      });
    };

    widget
    .once('ready', function () {
      expect($('#a0-lock .a0-notloggedin')).to.not.be.empty();
      expect($('#a0-lock .a0-loggedin')).to.be.empty();
      expect($('#a0-lock .a0-signup')).to.be.empty();
      expect($('#a0-lock .a0-reset')).to.be.empty();
      done();
    })
    .show({
      callbackURL: callbackURL,
      responseType: 'token',
      connections: ['facebook']
    });
  });

  it('should use only specified connections', function (done) {
    widget
    .once('ready', function () {
      expect(widget.$client.strategies.length).to.equal(4);

      expect(widget.$client.strategies[0].name).to.equal('twitter');
      expect(widget.$client.strategies[0].connections.length).to.equal(1);
      expect(widget.$client.strategies[0].connections[0].name).to.equal('twitter');

      expect(widget.$client.strategies[1].name).to.equal('google-oauth2');
      expect(widget.$client.strategies[1].connections.length).to.equal(1);
      expect(widget.$client.strategies[1].connections[0].name).to.equal('google-oauth2');

      expect(widget.$client.strategies[2].name).to.equal('auth0');
      expect(widget.$client.strategies[2].connections.length).to.equal(1);
      expect(widget.$client.strategies[2].connections[0].name).to.equal('dbTest');

      expect(widget.$client.strategies[3].name).to.equal('google-apps');
      expect(widget.$client.strategies[3].connections.length).to.equal(2);
      expect(widget.$client.strategies[3].connections[0].name).to.equal('google-app1');
      expect(widget.$client.strategies[3].connections[1].name).to.equal('google-app3');

      done();
    })
    .show({
      callbackURL: callbackURL,
      responseType: 'token',
      connections: ['twitter', 'google-oauth2', 'invalid-connection', 'google-app1', 'dbTest', 'google-app3']
    });
  });

  describe('When assetsUrl option is not specified', function () {
    beforeEach(function() {
      this.widget = new Auth0Lock(clientID, 'abc.contoso.com');
    });

    it('should use domain as assetsUrl if domain is not *.auth0.com', function () {
      expect(this.widget.$options.assetsUrl).to.equal('https://abc.contoso.com/');
    });

    it('should use default assetsUrl if domain is *.auth0.com', function () {
      this.widget = new Auth0Lock(clientID, 'abc.auth0.com:3000');

      expect(this.widget.$options.assetsUrl).to.equal('https://cdn.auth0.com/');
    });
  });

  describe('When assetsUrl option is specified', function () {
    it('should use provided assetsUrl and ignore defaults', function () {
      this.widget = new Auth0Lock(clientID, 'abc.contoso.com', {
        assetsUrl: 'https://sdk.myauth0-custom.com/'
      });

      expect(this.widget.$options.assetsUrl).to.equal('https://sdk.myauth0-custom.com/');
    });
  });

  describe('When cdn option is not specified', function () {
    beforeEach(function() {
      this.widget = new Auth0Lock(clientID, 'abc.contoso.com');
    });

    it('should use domain as cdn if domain is not *.auth0.com', function () {
      expect(this.widget.$options.cdn).to.equal('https://abc.contoso.com/w2/');
    });

    it('should use default cdn if domain is *.auth0.com', function () {
      this.widget = new Auth0Lock(clientID, 'abc.auth0.com');

      expect(this.widget.$options.cdn).to.equal('https://d19p4zemcycm7a.cloudfront.net/w2/');
    });
  });

  describe('When cdn option is specified', function () {
    it('should use provided cdn url and ignore defaults', function () {
      this.widget = new Auth0Lock(clientID, 'abc.contoso.com', {
        cdn: 'https://sdk.myauth0-custom.com/'
      });

      expect(this.widget.$options.cdn).to.equal('https://sdk.myauth0-custom.com/');
    });
  });

  describe('Sign In', function () {
    it('should signin with social connection', function (done) {
      client.login = function (options) {
        expect(options.connection).to.equal('google-oauth2');
        expect(options.username).to.be(undefined);
        done();
      };

      widget
      .once('ready', function () {
        bean.fire($('#a0-lock .a0-notloggedin .a0-iconlist [data-strategy="google-oauth2"]')[0], 'click');
      })
      .show({
        callbackURL: callbackURL,
        responseType: 'token'
      });
    });

    it('should signin with social connection specifying state', function (done) {
      client.login = function (options) {
        expect(options.state).to.equal('foo');
        expect(options.connection).to.equal('google-oauth2');
        expect(options.username).to.be(undefined);
        done();
      };

      widget
      .once('ready', function (mode) {
        bean.fire($('#a0-lock .a0-notloggedin .a0-iconlist [data-strategy="google-oauth2"]')[0], 'click');
      })
      .show({
        callbackURL: callbackURL,
        responseType: 'token',
        authParams: { state: 'foo' }
      });
    });

    it('should signin with social connection specifying connection_scope if one is provided', function (done) {
      var connection_scopes = {
        'twitter': ['grant1', 'grant2'],
        'google-oauth2': ['grant3'] };
      var connections = ['twitter', 'google-oauth2'];

      client.login = function (options) {
        expect(options.connection).to.equal('twitter');
        expect(options.username).to.be(undefined);
        expect(options.connection_scope.length).to.equal(2);
        expect(options.connection_scope[0]).to.equal('grant1');
        expect(options.connection_scope[1]).to.equal('grant2');
        expect(options.connection_scopes).to.not.be.empty();

        done();
      };

      widget
      .once('ready', function () {
        bean.fire($('#a0-lock .a0-notloggedin .a0-iconlist [data-strategy="twitter"]')[0], 'click');
      })
      .show({ callbackURL: callbackURL, responseType: 'token', connections: connections, authParams: { connection_scopes: connection_scopes }});
    });

    it('should signin with social connection with undefined connection_scope if one is not provided (does not throw)', function (done) {
      var connection_scopes = {
        'twitter': ['grant1', 'grant2'] };
      var connections = ['twitter', 'google-oauth2'];

      client.login = function (options) {
        expect(options.connection).to.equal('google-oauth2');
        expect(options.username).to.be(undefined);
        expect(options.connection_scope).to.be(undefined);
        expect(options.connection_scopes).to.not.be.empty();

        done();
      };

      widget
      .once('ready', function () {
        bean.fire($('#a0-lock .a0-notloggedin .a0-iconlist [data-strategy="google-oauth2"]')[0], 'click');
      })
      .show({ callbackURL: callbackURL, responseType: 'token', connections: connections, authParams: { connection_scopes: connection_scopes }});
    });

    it('should signin with database connection (auth0 strategy)', function (done) {
      client.login = function (options) {
        expect(options.connection).to.equal('dbTest');
        expect(options.username).to.equal('<EMAIL>');
        expect(options.password).to.equal('<PASSWORD>');
        done();
      };

      widget
      .once('ready', function () {
        $('#a0-lock .a0-notloggedin .a0-emailPassword .a0-email input').val('<EMAIL>');
        $('#a0-lock .a0-notloggedin .a0-emailPassword .a0-password input').val('<PASSWORD>');
        $('#a0-lock .a0-notloggedin .a0-emailPassword .a0-action button.a0-primary').trigger('click');
      })
      .show({ callbackURL: callbackURL, responseType: 'token', authParams: { state: 'foo' }});
    });

    it('should signin with database connection (auth0 strategy) specifying state authParam', function (done) {
      client.login = function (options) {
        expect(options.state).to.equal('foo');
        expect(options.connection).to.equal('dbTest');
        expect(options.username).to.equal('<EMAIL>');
        expect(options.password).to.equal('xyz');
        done();
      };

      widget
      .once('ready', function () {
        $('#a0-lock .a0-notloggedin .a0-emailPassword .a0-email input').val('<EMAIL>');
        $('#a0-lock .a0-notloggedin .a0-emailPassword .a0-password input').val('<PASSWORD>');
        $('#a0-lock .a0-notloggedin .a0-emailPassword .a0-action button.a0-primary').trigger('click');
      })
      .show({ callbackURL: callbackURL, responseType: 'token', authParams: { state: 'foo' }});
    });

    it('should signin with adldap connection (auth0-adldap strategy)', function (done) {
      client.login = function (options) {
        expect(options.connection).to.equal('adldap');
        expect(options.username).to.equal('peter');
        expect(options.password).to.equal('<PASSWORD>');
        done();
      };

      widget
      .once('ready', function() {
        $('#a0-lock .a0-notloggedin .a0-emailPassword .a0-email input').val('<EMAIL>');
        $('#a0-lock .a0-notloggedin .a0-emailPassword .a0-password input').val('<PASSWORD>');
        $('#a0-lock .a0-notloggedin .a0-emailPassword .a0-action button.a0-primary').trigger('click');
      })
      .show({
        callbackURL: callbackURL,
        responseType: 'token',
        defaultUserPasswordConnection: 'adldap'
      });
    });

    it('should signin with enterprise connection', function (done) {
      client.login = function (options) {
        expect(options.connection).to.equal('contoso');
        expect(options.username).to.be(undefined);
        done();
      };
      widget
      .once('ready', function () {
        $('#a0-lock .a0-notloggedin .a0-emailPassword .a0-email input').val('<EMAIL>');
        // we need this to check if password is ignored or not in validation
        bean.fire($('#a0-lock .a0-notloggedin .a0-emailPassword .a0-email input')[0], 'input');
        $('#a0-lock .a0-notloggedin .a0-emailPassword .a0-action button.a0-primary').trigger('click');
      })
      .show({
        callbackURL: callbackURL,
        responseType: 'token'
      });
    });

    it('should signin with enterprise connection specifying authParams', function (done) {
      client.login = function (options) {
        expect(options.state).to.equal('foo');
        expect(options.connection).to.equal('contoso');
        expect(options.username).to.be(undefined);
        done();
      };

      widget
      .once('ready', function () {
        $('#a0-lock .a0-notloggedin .a0-emailPassword .a0-email input').val('<EMAIL>');
        // we need this to check if password is ignored or not in validation
        bean.fire($('#a0-lock .a0-notloggedin .a0-emailPassword .a0-email input')[0], 'input');
        $('#a0-lock .a0-notloggedin .a0-emailPassword .a0-action button.a0-primary').trigger('click');
      })
      .show({ callbackURL: callbackURL, responseType: 'token', authParams: { state: 'foo' }});
    });

    it('should send extra authParams to login', function (done) {
      client.login = function (options) {
        expect(options.access_type).to.equal('offline');
        done();
      };

      widget
      .once('ready', function () {
        bean.fire($('#a0-lock .a0-notloggedin .a0-iconlist [data-strategy="google-oauth2"]')[0], 'click');
      })
      .show({ callbackURL: callbackURL, responseType: 'token', authParams: { access_type: 'offline' } });
    });

    describe('when requires_username is enabled', function() {

      beforeEach(function() {
        this.options = this.options || {};
        // Mock `_isUsernameRequired` so it asumes database has enabled
        // requires_username on it's configuration
        this.options._isUsernameRequired = function() { return true; };
      });

      it('should invalidate an empty username', function (done) {
        var auth0 = widget;
        var email = '<EMAIL>';
        var password = '<PASSWORD>';

        auth0
        .once('signin ready', function() {
          $('#a0-signin_easy_password').val(password);
          $('#a0-signin_easy_repeat_password').val(password);

          bean.fire($('.a0-signin form')[0], 'submit');

          expect($('.a0-email .a0-error-input')).to.not.be.empty();
          done();
        })
        .showSignin(this.options);
      });

      it('should invalidate an invalid username', function (done) {
        var auth0 = widget;
        var username = '1.1.1.1';
        var password = '<PASSWORD>';

        auth0
        .once('signin ready', function() {
          $('#a0-signin_easy_email').val(username);
          $('#a0-signin_easy_password').val(password);
          $('#a0-signin_easy_repeat_password').val(password);

          bean.fire($('.a0-signin form')[0], 'submit');

          expect($('.a0-email .a0-error-input')).to.not.be.empty();
          expect($('.a0-email .a0-error-input .a0-error-message')).to.not.be.empty();
          expect($('.a0-error-message').text()).to.equal(auth0.options.i18n.t('invalid'));
          done();
        })
        .showSignin(this.options);
      });

      it('should still invalidate an invalid email', function (done) {
        var auth0 = widget;
        var email = '<EMAIL>';
        var password = '<PASSWORD>';

        auth0
        .once('signin ready', function() {
          $('#a0-signin_easy_email').val(email);
          $('#a0-signin_easy_password').val(password);
          $('#a0-signin_easy_repeat_password').val(password);

          bean.fire($('.a0-signin form')[0], 'submit');

          expect($('.a0-email .a0-error-input')).to.not.be.empty();
          expect($('.a0-email .a0-error-input .a0-error-message')).to.not.be.empty();
          expect($('.a0-error-message').text()).to.equal(auth0.options.i18n.t('invalid'));
          done();
        })
        .showSignin(this.options);
      });

      it('should send valid username on submit', function (done) {
        var auth0 = widget;
        var username = 'pepe';
        var email = '<EMAIL>';
        var password = '<PASSWORD>';

        client.login = function(options) {
          expect(options.username).to.equal(username);
          expect(options.password).to.equal(password);
          done();
        }

        auth0
        .once('signin ready', function() {
          $('#a0-signin_easy_email').val(username);
          $('#a0-signin_easy_password').val(password);
          $('#a0-signin_easy_repeat_password').val(password);

          bean.fire($('.a0-signin form')[0], 'submit');
        })
        .showSignin(this.options);
      });

      it('should still send valid email on submit', function (done) {
        var auth0 = widget;
        var email = '<EMAIL>';
        var password = '<PASSWORD>';

        client.login = function(options) {
          expect(options.username).to.equal(email);
          expect(options.password).to.equal(password);
          done();
        }

        auth0
        .once('signin ready', function() {
          $('#a0-signin_easy_email').val(email);
          $('#a0-signin_easy_password').val(password);
          $('#a0-signin_easy_repeat_password').val(password);

          bean.fire($('.a0-signin form')[0], 'submit');
        })
        .showSignin(this.options);
      });
    });
  });

  describe('Sign Up with database connection', function () {

    it('should show only signup view when user clicks on signup button', function (done) {
      widget
      .once('signin ready', function () {
        bean.fire($('#a0-lock .a0-notloggedin .a0-emailPassword .a0-action a.a0-sign-up')[0], 'click');
      })
      .once('signup ready', function (){
        expect($('#a0-lock .a0-notloggedin')).to.be.empty();
        expect($('#a0-lock .a0-loggedin')).to.be.empty();
        expect($('#a0-lock .a0-reset')).to.be.empty();
        expect($('#a0-lock .a0-signup')).to.not.be.empty();
        done();
      })
      .show({
        callbackURL: callbackURL,
        responseType: 'token'
      });
    });

    it('should call auth0.a0-signup', function (done) {
      client.signup = function (options) {
        expect(options.connection).to.equal('dbTest');
        expect(options.username).to.equal('<EMAIL>');
        expect(options.password).to.equal('<PASSWORD>');
        done();
      };

      widget
      .once('signin ready', function () {
        bean.fire($('#a0-lock .a0-notloggedin .a0-emailPassword .a0-action a.a0-sign-up')[0], 'click');
      })
      .once('signup ready', function () {
        $('#a0-lock .a0-signup .a0-emailPassword .a0-email input').val('<EMAIL>');
        $('#a0-lock .a0-signup .a0-emailPassword .a0-password input').val('<PASSWORD>');
        $('#a0-lock .a0-signup .a0-emailPassword .a0-action button.a0-primary').trigger('click');
      })
      .show({
        callbackURL: callbackURL,
        responseType: 'token'
      });
    });
  });

  describe('Change Password with database connection', function () {
    it('should show reset view when user clicks on change password button', function (done) {
      widget
      .once('signin ready', function () {
        bean.fire($('#a0-lock .a0-notloggedin .a0-emailPassword .a0-action a.a0-forgot-pass')[0], 'click');
      })
      .once('reset ready',function () {
        expect($('#a0-lock .a0-notloggedin')).to.be.empty();
        expect($('#a0-lock .a0-loggedin')).to.be.empty();
        expect($('#a0-lock .a0-signup')).to.be.empty();
        expect($('#a0-lock .a0-reset')).to.not.be.empty();
        done();
      })
      .show({
        callbackURL: callbackURL,
        responseType: 'token'
      });
    });

    it('should call auth0.changePassword', function (done) {
      client.changePassword = function (options) {
        expect(options.connection).to.equal('dbTest');
        expect(options.username).to.equal('<EMAIL>');
        expect(options.password).to.equal('<PASSWORD>');
        done();
      };

      widget
      .once('ready', function () {
        bean.fire($('#a0-lock .a0-notloggedin .a0-emailPassword .a0-action a.a0-forgot-pass')[0], 'click');
      })
      .once('reset ready', function () {
        $('#a0-lock .a0-reset .a0-emailPassword .a0-email input').val('<EMAIL>');
        $('#a0-lock .a0-reset .a0-emailPassword .a0-password input').val('<PASSWORD>');
        $('#a0-lock .a0-reset .a0-emailPassword .a0-repeatPassword input').val('<PASSWORD>');
        $('#a0-lock .a0-reset .a0-emailPassword .a0-action button.a0-primary').trigger('click');
      })
      .show({
        callbackURL: callbackURL,
        responseType: 'token'
      });
    });
  });

  describe('placeholder fallback support', function() {
    it('should have a0-no-placeholder-support class when not supported (' + placeholderSupportPrefix + 'supported)', function(done) {
      widget
      .once('ready', function() {
        var hasClass = $('#a0-lock .a0-overlay').hasClass('a0-no-placeholder-support');
        expect(hasClass).to.be(!placeholderSupport);
        if (!placeholderSupport) {
          var $fallback = $('#a0-lock .a0-no-placeholder-support .a0-sad-placeholder');
          expect($fallback).to.not.be.empty()
          expect($fallback.css('display')).to.equal('block');
        };
        done();
      })
      .show()
    });

    it('should not have a0-no-placeholder-support class when supported (' + placeholderSupportPrefix + 'supported)', function(done) {
      widget
      .once('ready', function() {
        var hasClass = $('#a0-lock .a0-overlay').hasClass('a0-no-placeholder-support');
        expect(!hasClass).to.be(placeholderSupport);
        if (placeholderSupport) {
          var $fallback = $('#a0-lock .a0-no-placeholder-support .a0-sad-placeholder');
          expect($fallback).to.be.empty();
          expect($('#a0-lock .a0-sad-placeholder').css('display')).to.equal('none');
        };
        done();
      })
      .show();
    });
  });

});


<|start_filename|>lib/i18n/index.js<|end_filename|>
var dics_data = {
  'ar': require('../../i18n/ar.json'),
  'de': require('../../i18n/de.json'),
  'en': require('../../i18n/en.json'),
  'es': require('../../i18n/es.json'),
  'fr': require('../../i18n/fr-FR.json'),
  'fr-FR': require('../../i18n/fr-FR.json'),
  'he': require('../../i18n/he.json'),
  'it': require('../../i18n/it.json'),
  'ja': require('../../i18n/ja.json'),
  'nb-NO': require('../../i18n/nb-NO.json'),
  'nl': require('../../i18n/nl-NL.json'),
  'nl-NL': require('../../i18n/nl-NL.json'),
  'pt': require('../../i18n/pt.json'),
  'pt-BR': require('../../i18n/pt-BR.json'),
  'ru': require('../../i18n/ru.json'),
  'tlh': require('../../i18n/tlh.json'),
  'tr': require('../../i18n/tr.json'),
  'zh': require('../../i18n/zh.json')
};

var default_dict = dics_data['en'];

function findProp(o, s) {
    s = s.replace(/\[(\w+)\]/g, ':$1'); // convert indexes to properties
    s = s.replace(/^\:/, '');           // strip a leading dot
    var a = s.split(':');
    while (a.length) {
        var n = a.shift();
        if (n in o) {
            o = o[n];
        } else {
            return;
        }
    }
    return o;
}

function Dictionary (data) {
  this._data = data;
}

Dictionary.prototype.t = function (key) {
  return findProp(this._data, key) || findProp(default_dict, key);
};

module.exports.getDict = function ( langOrDict ) {

  if (!langOrDict) {
    return new Dictionary(default_dict);
  }

  if ( typeof langOrDict === 'string' ) {
    var dict = dics_data[langOrDict] || dics_data[langOrDict.split('-')[0]];
    return new Dictionary(dict);
  } else {
    return new Dictionary(langOrDict);
  }
};


<|start_filename|>test/gravatar.tests.js<|end_filename|>

/* global bean */

var clientID  = '0HP71GSd6PuoRYJ3DXKdiXCUUdGmBbup';
var domain    = 'mdocs.auth0.com';

function type(input, value) {
  input.val(value);
  bean.fire(input[0], 'input');
}

function isVisible(element) {
  return !element.hasClass('a0-hide');
}

describe('gravatar', function () {
  var email, avatar, icon, iconImg;

  beforeEach(function (done) {
    this.widget = new Auth0Lock(clientID, domain);
    this.options = {
      rememberLastLogin: false,
      integratedWindowsLogin: false
    };
    done();
  });

  afterEach(function (done) {
    this.options = null;
    global.window.Auth0 = null;
    this.widget.hide(done);
  });

  it('should display gravatar when email has an associated gravatar account', function (done) {
    var expectedGravatarURL = 'https://www.gravatar.com/avatar/9d8d8bff4484ddadf83684d88cb10188?d=404';
    var gravatarEmail = '<EMAIL>';

    // Should never happen
    this.widget.on('avatar shown', function () {
      expect(false).to.be.equal(true);
    });

    this.widget.on('icon shown', function () {
      expect(isVisible(avatar)).to.be.equal(false);
      expect(isVisible(icon)).to.be.equal(true);
      expect(iconImg.attr('src')).to.be.equal(expectedGravatarURL);
      done();
    });

    this.widget.on('ready', function () {
      email   = $('#a0-lock .a0-notloggedin .a0-emailPassword .a0-email input');
      avatar  = $('#a0-lock .a0-header .a0-avatar');
      icon    = $('#a0-lock .a0-header .a0-image');
      iconImg = $('#a0-lock .a0-header .a0-image img');

      expect(email).not.to.be.empty();
      expect(avatar).not.to.be.empty();
      expect(icon).not.to.be.empty();
      expect(iconImg).not.to.empty();

      type(email, gravatarEmail);
    });

    this.widget.show(this.options);

  });

  it('should not display gravatar when email has no gravatar account', function (done) {
    var gravatarEmail = '<EMAIL>';

    // Should never happen
    this.widget.on('icon shown', function () {
      expect(false).to.be.equal(true);
    });

    this.widget.on('avatar shown', function () {
      expect(isVisible(avatar)).to.be.equal(true);
      expect(isVisible(icon)).to.be.equal(false);
      done();
    });

    this.widget.on('ready', function () {
      email   = $('#a0-lock .a0-notloggedin .a0-emailPassword .a0-email input');
      avatar  = $('#a0-lock .a0-header .a0-avatar');
      icon    = $('#a0-lock .a0-header .a0-image');
      iconImg = $('#a0-lock .a0-header .a0-image img');

      expect(email).not.to.be.empty();
      expect(avatar).not.to.be.empty();
      expect(icon).not.to.be.empty();
      expect(iconImg).not.to.empty();

      type(email, gravatarEmail);
    });

    this.widget.show(this.options);
  });
});


<|start_filename|>i18n/pt-BR.json<|end_filename|>
{
  "loadingTitle": "Carregando...",
  "close": "Fechar",
  "signin": {
    "title": "Entrar",
    "action": "Entrar",
    "all": "Mostrar todos",
    "strategyEmailEmpty": "O e-mail deve ser preenchido.",
    "strategyEmailInvalid": "O email é inválido.",
    "strategyDomainInvalid": "O domínio {domain} não foi informado.",
    "signupText": "Registre-se",
    "forgotText": "Esqueceu sua senha?",
    "emailPlaceholder": "E-mail",
    "usernamePlaceholder": "Nome de Usuário",
    "passwordPlaceholder": "<PASSWORD>",
    "separatorText": "ou",
    "serverErrorText": "Houve um erro ao efetuar o login.",
    "returnUserLabel": "Da última vez que você fez login usando...",
    "wrongEmailPasswordErrorText": "E-mail ou senha inválidos.",
    "or": "... ou entre usando",
    "loadingMessage": "Entrar com {connection}..."
  },
  "signup": {
    "description": "",
    "title": "Cadastre-se",
    "action": "Cadastre-se",
    "emailPlaceholder": "E-mail",
    "passwordPlaceholder": "<PASSWORD>",
    "cancelAction": "Cancelar",
    "headerText": "Por favor, digite seu e-mail e senha",
    "footerText": "",
    "enterpriseEmailWarningText": "Este domínio {domain} foi configurado para Sign-On único e você não pode criar uma conta. Tente fazer o login em vez disso.",
    "serverErrorText": "Houve um erro ao efetuar o login."
  },
  "reset": {
    "title": "Redefinir senha",
    "action": "Enviar",
    "emailPlaceholder": "E-mail",
    "passwordPlaceholder": "<PASSWORD>",
    "repeatPasswordPlaceholder": "<PASSWORD>ha",
    "cancelAction": "Cancelar",
    "successText": "Já enviamos um e-mail para redefinir sua senha.",
    "enterSamePasswordText": "Por favor digite a mesma senha.",
    "headerText": "Por favor, digite seu e-mail e a senha nova. Nós lhe enviaremos um e-mail para confirmar a alteração de senha.",
    "serverErrorText": "Houve um erro ao redefinir a senha."
  }
}


<|start_filename|>i18n/fr-FR.json<|end_filename|>
{
  "loadingTitle": "Veuillez patienter...",
  "close": "Fermer",
  "windowsAuthTitle": "Connexion Windows",
  "signin": {
    "title": "Connexion",
    "action": "Connexion",
    "all": "Afficher tout",
    "strategyEmailEmpty": "Le courriel est vide.",
    "strategyEmailInvalid": "Le courriel n'est pas valide.",
    "strategyDomainInvalid": "Le domaine {domain} n'a pas été configuré.",
    "signupText": "Inscrivez-vous",
    "forgotText": "Vous avez oublié votre mot de passe ?",
    "emailPlaceholder": "Courriel",
    "usernamePlaceholder": "<NAME>'utilisateur",
    "passwordPlaceholder": "<PASSWORD>",
    "separatorText": "ou",
    "serverErrorText": "Erreur lors de la connexion.",
    "returnUserLabel": "Lors de votre dernière connexion vous avez utilisé...",
    "domainUserLabel": "Vous êtes connecté depuis le réseau de votre entreprise...",
    "wrongEmailPasswordErrorText": "Courriel ou mot de passe incorrect.",
    "or": "... ou connectez-vous à l'aide de",
    "loadingMessage": "Connexion à l'aide de {connection}..."
  },
  "signup": {
    "description": "",
    "title": "Inscrivez-vous",
    "action": "Inscrivez-vous",
    "emailPlaceholder": "Courriel",
    "passwordPlaceholder": "<PASSWORD>",
    "cancelAction": "Annuler",
    "headerText": "Veuillez entrer votre courriel et mot de passe",
    "footerText": "",
    "enterpriseEmailWarningText": "Ce domaine {domain} a été configuré pour le Single Sign On et vous ne pouvez pas créer de compte. Essayez de vous connecter à un compte existant.",
    "serverErrorText": "Erreur lors de l'inscription.",
    "userExistsErrorText": "Cet utilisateur existe déjà."
  },
  "reset": {
    "title": "Réinitialiser votre mot de passe",
    "action": "Envoyer",
    "emailPlaceholder": "Courriel",
    "passwordPlaceholder": "<PASSWORD> de passe",
    "repeatPasswordPlaceholder": "<PASSWORD> nouveau mot de passe",
    "cancelAction": "Annuler",
    "successText": "Vous allez recevoir sous quelques minutes un courriel vous indiquant comment réinitialiser votre mot de passe.",
    "enterSamePasswordText": "S'il vous plaît entrez le même mot de passe.",
    "headerText": "Veuillez saisir votre courriel et mot de passe. Nous vous enverrons un courriel pour confirmer le changement de mot de passe.",
    "serverErrorText": "Erreur de traitement los de réinitialisation du mot de passe.",
    "userDoesNotExistErrorText": "Utilisateur introuvable."
  }
}


<|start_filename|>test/password_strength.tests.js<|end_filename|>
/* global bean, $ */

var clientID  = 'QiJzNJoKaiQdmGg9ldGYGq1BOc378fyq';
var domain    = 'lock-pwd-strength-tests.auth0.com';

function type(input, value) {
  input.val(value);
  input.focus();
  bean.fire(input[0], 'keydown');
  bean.fire(input[0], 'keyup');
  bean.fire(input[0], 'input');
}

describe('password strength', function () {
  var password;

  beforeEach(function (done) {
    this.widget = new Auth0Lock(clientID, domain);
    this.options = {
      rememberLastLogin: false,
      integratedWindowsLogin: false,
      assetsUrl: ''
      // connections: ['Username-Password-Authentication']
    };
    done();
  });

  afterEach(function (done) {
    this.options = null;
    global.window.Auth0 = null;
    this.widget.hide(done);
  });

  it('display message when password does not meet criteria', function (done) {

    this.widget.once('ready', function () {
      password  = $('#a0-lock .a0-emailPassword .a0-password input');

      expect(password).not.to.be.empty();
      expect($('#a0-lock .a0-password_policy').html()).to.be.equal('');
      // expect($('#a0-lock .a0-panel').hasClass('a0-active-pwd-strength')).to.be.equal(false);
      // expect($('#a0-lock .a0-password_policy .a0-checked').length).to.be.equal(0);

      type(password, '<PASSWORD>');

      // Rules are rendered
      expect($('#a0-lock .a0-password_policy').html()).not.to.be.equal('');
      // Only the lower case rule is satisfied
      expect($('#a0-lock .a0-password_policy .a0-checked').length).to.be.equal(1);
      // TODO Panel does contain class that displays rules
      // expect($('#a0-lock .a0-panel').hasClass('a0-active-pwd-strength')).to.be.equal(true);

      done();
    });
    this.widget.showSignup(this.options);
  });

  it('should not display message when password meets criteria', function (done) {

    this.widget.once('ready', function () {
      password  = $('#a0-lock .a0-emailPassword .a0-password input');

      expect(password).not.to.be.empty();
      expect($('#a0-lock .a0-password_policy').html()).to.be.equal('');
      // expect($('.a0-panel').hasClass('a0-active-pwd-strength')).to.be.equal(false);
      // expect($('#a0-lock .a0-password_policy .a0-checked').length).to.be.equal(0);

      type(password, '<PASSWORD>!');

      // Rules are rendered
      expect($('#a0-lock .a0-password_policy').html()).not.to.be.equal('');
      // All 6 rules are satisfied
      expect($('#a0-lock .a0-password_policy .a0-checked').length).to.be.equal(6);

      // TODO Panel does not contain class that displays rules
      // expect($('.a0-panel').hasClass('a0-active-pwd-strength')).to.be.equal(false);

      done();
    });

    this.widget.showSignup(this.options);
  });
});



<|start_filename|>lib/is-small-screen/index.js<|end_filename|>
module.exports = function () {
  return window.matchMedia && !window.matchMedia( "(min-width: 340px)" ).matches;
};

<|start_filename|>lib/mode-kerberos/index.js<|end_filename|>
/**
 * Module dependencies.
 */

var _ = require('underscore');
var $ = require('../bonzo-augmented');
var Emitter = require('events').EventEmitter;
var create = require('../object-create');
var template = require('./loggedin.ejs');
var buttonTmpl  = require('../html/zocial-button.ejs');
var stop = require('../stop-event');

/**
 * Expose KerberosPanel
 */

module.exports = KerberosPanel;

/**
 * Create `KerberosPanel`
 *
 * @param {Auth0Lock} widget
 * @param {Object} options
 * @constructor
 */

function KerberosPanel(widget, options) {
  if (!(this instanceof KerberosPanel)) {
    return new KerberosPanel(widget, options);
  };

  // Both `widget` and `options` are required
  if (2 !== arguments.length) {
    throw new Error('Missing parameters for KerberosPanel');
  }

  this.name = 'kerberos'
  this.widget = widget;
  this.options = this.resolveOptions(options);
  this.el = null;

  Emitter.call(this);
}

/**
 * Inherit from `EventEmitter`
 */

KerberosPanel.prototype = create(Emitter.prototype);

/**
 * Query for elements at `this.el` context
 *
 * @param {String} selector
 * @return {BonzoAugmented}
 * @public
 */
KerberosPanel.prototype.query = function(selector) {
  if (!this.el) throw new Error('Can\'t get element since no `el` is set to local context');
  return $(selector, this.el);
};

/**
 * Create `el`
 *
 * @param {Object} options
 * @return {NodeElement}
 * @public
 */

KerberosPanel.prototype.create = function(options) {
  var opts = this.resolveOptions(options);
  var widget = this.widget;

  this.el = $.create(widget.render(template, opts))[0];
  this.bindAll();
  return this.el;
}

/**
 * Return `el` or create it
 *
 * @param {Object} options
 * @return {NodeElement}
 * @public
 */

KerberosPanel.prototype.render = function() {
  return null != this.el
    ? this.el
    : this.create.apply(this, arguments);
}

/**
 * Resolves login options passed to template
 *
 * @param {Object} options
 * @return {Object}
 * @private
 */

KerberosPanel.prototype.resolveOptions = function(options) {
  return _.extend({}, this.widget.options,  this.options, options);
};

/**
 * Bind events to `this.el`, like submit
 */
KerberosPanel.prototype.bindAll = function() {
  var self = this;
  var widget = this.widget;
  var options = this.options;

  var connection = widget.$ssoData.connection;
  //this could be ad or auth0-adldap
  var strategy_name = widget.$ssoData.strategy;
  var strategy = widget.$strategies[strategy_name];

  if (!strategy) return;

  this.query('form').a0_on('submit', function (e) {
    stop(e);
    widget._signInEnterprise(e);
  });

  var button = $.create(buttonTmpl({
    use_big_buttons: true,
    name: strategy_name,
    title: options.i18n.t('windowsAuthTitle').replace('{connection}', connection),
    css: strategy.css,
    imageicon: strategy.imageicon,
  }));

  this.query('.a0-last-time').html(options.i18n.t('signin:domainUserLabel'));

  this.query('.a0-strategy div').remove();

  this.query('.a0-strategy')
    .append(button);

  this.query('.a0-strategy .a0-zocial[data-strategy]').a0_on('click', function (e) {
    stop(e);
    widget._signinSocial(strategy_name, connection, null, self);
  });

  this.query('.a0-all').a0_on('click', function (e) {
    stop(e);
    // no need to check other panels since
    // no reset nor signup modes allow for
    // return user experience...
    widget._signinPanel(self.options);
  });
}


<|start_filename|>i18n/nb-NO.json<|end_filename|>
{
  "loadingTitle":                  "Vennligst vent...",
  "close":                         "Lukk",
  "windowsAuthTitle":              "Windows-autentisering",
  "invalid":                       "Ugyldig",
  "mustMatch":                     "Må tilsvare",
  "loginSocialButton":             "Logg inn med {connection:title}",
  "signupSocialButton":            "Registrer med {connection:title}",
  "signin": {
    "title":                       "Innlogging",
    "action":                      "Logg inn",
    "actionDomain":                "Logg inn {domain}",
    "all":                         "Vis alle",
    "strategyEmailEmpty":          "E-posten er ikke utfylt.",
    "strategyEmailInvalid":        "E-posten er ugyldig.",
    "strategyDomainInvalid":       "Domenet {domain} er ikke konfigurert.",
    "signupText":                  "Registrer",
    "forgotText":                  "Tilbakestill passord",
    "cancelAction":                "Avbryt",
    "emailPlaceholder":            "E-post",
    "usernamePlaceholder":         "Brukernavn",
    "passwordPlaceholder":         "<PASSWORD>",
    "separatorText":               "eller",
    "serverErrorText":             "Det oppstod en feil under innlogging",
    "returnUserLabel":             "Sist gang logget du inn med...",
    "domainUserLabel":             "Du er tilkoblet ditt nettverk...",
    "wrongEmailPasswordErrorText": "Feil e-post eller passord.",
    "or":                          "... eller logg inn med",
    "loadingMessage":              "Logger inn med {connection}...",
    "popupCredentials":            "Skriv inn identifikasjon i pop-up-vinduet",
    "userClosedPopup":             "Pop-up-vindu lukket. Prøv igjen.",
    "userConsentFailed":           "Nødvendige tilganger ble ikke gitt. Vennligst prøv igjen."
  },
  "signup": {
    "description":                 "",
    "title":                       "Registrer",
    "action":                      "Registrer",
    "emailPlaceholder":            "E-post",
    "passwordPlaceholder":         "<PASSWORD> passord",
    "cancelAction":                "Avbryt",
    "headerText":                  "Vennligst skriv inn e-post og passord",
    "footerText":                  "",
    "enterpriseEmailWarningText":  "Domenet {domain} er konfigurert med Single Sign On og du kan ikke opprette en konto selv. Forsøk å logge inn istedet.",
    "serverErrorText":             "Det oppstod en feil under innlogging.",
    "userExistsErrorText":         "Brukeren finnes allerede.",
    "invalidPassword":             "Passordet er for svakt."
  },
  "reset": {
    "title":                       "Tilbakestill passord",
    "action":                      "Send",
    "emailPlaceholder":            "E-post",
    "passwordPlaceholder":         "<PASSWORD>",
    "repeatPasswordPlaceholder":   "<PASSWORD>",
    "cancelAction":                "Avbryt",
    "successText":                 "Du har blitt tilsendt en e-post for å tilbakestille passordet ditt.",
    "enterSamePasswordText":       "Vennligst skriv inn det samme passordet.",
    "headerText":                  "Vennligst skriv inn e-post og ditt nye passord. Vi sender deg en e-post for å bekrefte endringen.",
    "serverErrorText":             "Det oppstod en feil under tilbakestilling av passordet.",
    "userDoesNotExistErrorText":   "Brukeren finnes ikke."
  }
}


<|start_filename|>lib/header/icon-container.js<|end_filename|>
var EventEmitter = require('events').EventEmitter;

var whichAnimationEvent = require('../supports-animation');
var ocreate = require('../object-create');

// XXX This number should match the value in less .animation.match duration
var ANIMATION_TIMEOUT_MS = 300;

module.exports = IconContainerView;

/**
 *
 * IconContainerView
 *
 * Class that handles all the complexity of the animation
 * and display of icon and avatar in header.
 *
 * @constructor
 * @param {Object} widget
 * @param {Object} options
 *
 * @public
 */

function IconContainerView (header, options) {
  this.header = header;
  this.options = options;

  this.animationEnd = whichAnimationEvent();

  this.queue = [];
}

/**
 * Inherit from `EventEmitter`
 */

IconContainerView.prototype = ocreate(EventEmitter.prototype);

/**
 * Query for elements at `this.header.el` context
 *
 * @param {String} selector
 * @return {BonzoAugmented}
 * @public
 */

IconContainerView.prototype.query = function(selector) {
  return this.header.query(selector);
}

IconContainerView.prototype.avatar = function() {
  return this.query('.a0-avatar');
}

IconContainerView.prototype.img = function() {
  return this.query('.a0-image img');
}

IconContainerView.prototype.imgContainer = function() {
  return this.query('.a0-image');
}

// TODO Refactor me! I'm identical to _hide
IconContainerView.prototype._show = function (el, cb) {
  var self = this;

  if(!el.hasClass('a0-hide')) {
    return cb();
  }

  // IE 9 :(
  if (!self.animationEnd){
    el.removeClass('a0-hide');
    return cb();
  }

  el.removeClass('a0-animated a0-fast a0-flipInX a0-flipOutX');
  el.a0_once(self.animationEnd, function () {
    el.removeClass('a0-animated a0-fast a0-flipInX a0-flipOutX');
    cb();
  });
  el.addClass('a0-animated a0-fast a0-flipInX');
  el.removeClass('a0-hide');
};

IconContainerView.prototype._hide = function (el, cb) {
  var self = this;

  if(el.hasClass('a0-hide')) {
    return cb();
  }

  // IE 9 :(
  if (!self.animationEnd){
    el.addClass('a0-hide');
    return cb();
  }

  el.removeClass('a0-animated a0-fast a0-flipInX a0-flipOutX');
  el.a0_once(self.animationEnd, function () {
    el.removeClass('a0-animated a0-fast a0-flipOutX a0-flipInX');
    el.addClass('a0-hide');

    cb();
  });
  el.addClass('a0-animated a0-fast a0-flipOutX');
};

IconContainerView.prototype._showIcon = function (cb) {
  var self = this;
  return this._show(this.imgContainer(), function () {
    self.emit('icon shown');
    cb();
  });
};

IconContainerView.prototype._showAvatar = function (cb) {
  var self = this;
  return this._show(this.avatar(), function () {
    self.emit('avatar shown');
    cb();
  });
};

IconContainerView.prototype._hideIcon = function (cb) {
  var self = this;
  return this._hide(this.imgContainer(), function () {
    self.emit('icon hidden');
    cb();
  });
};

IconContainerView.prototype._hideAvatar = function (cb) {
  var self = this;
  return this._hide(this.avatar(), function () {
    self.emit('avatar hidden');
    cb();
  });
};

IconContainerView.prototype._onError = callbackify(function (cb, self) {
  clearTimeout(self.timer);
  self.img().a0_off('load');
  self.img().a0_off('error');

  self.imgContainer().removeClass('a0-gravatar');

  self._hideIcon(function () {
    if (self.options.icon) {
      self.img().attr('src', self.options.icon);
      self._showIcon(cb);
    } else {
      self._showAvatar(cb);
    }
  });
});

IconContainerView.prototype._onLoad = callbackify(function (cb, self) {
  clearTimeout(self.timer);
  self.img().a0_off('error');
  self.img().a0_off('load');

  self.query('.a0-image').addClass('a0-gravatar');

  self._hideAvatar(function () {
    self._showIcon(cb);
  });
});

IconContainerView.prototype._processQueue = function () {
  var self = this;

  if (!this.queue.length || this.processing) {
    return;
  }

  var element = this.queue.pop();

  self.processing = true;
  element(function () {
    self.processing = false;
    self._processQueue();
  });
};

/**
 * Show image
 *
 * @param {String} url
 * @private
 */

IconContainerView.prototype.set = function(url) {
  var self = this;

  this.queue.push(function (cb) {
    // URL already set, nothing to do here :)
    if (self.img().attr('src') === url) {
      return cb();
    }
    // XXX Super hack: sometimes neither error nor load
    // executes, that's why this timer is required.
    self.timer = setTimeout(cb, ANIMATION_TIMEOUT_MS);
    self.img().a0_once('error', self._onError(cb, self));
    self.img().a0_once('load', self._onLoad(cb, self));


    self._hideIcon(function () {
      self.img().attr('src', url);
    });

  });
  this._processQueue();
};


/**
 * Restore image to default image
 *
 * @private
 */

IconContainerView.prototype.reset = function () {
  var self = this;

  if (this.options.icon) {
    this.queue.push(function (cb) {
      if (self.img().attr('src') !== self.options.icon) {
        self._hideIcon(function () {
          self.imgContainer().removeClass('a0-gravatar');
          self.img().attr('src', self.options.icon);
          self._showIcon(cb);
        });
        return;
      }
      self.imgContainer().removeClass('a0-gravatar');
      cb();
    });
  } else {
    this.queue.push(function (cb) {
      self._hideIcon(function () {
        self.imgContainer().removeClass('a0-gravatar');
        self._showAvatar(cb);
      });
    });
  }
  this._processQueue();
};

function callbackify(fn) {
  return function (cb, self) {
    return function () {
      fn.apply(self, [cb, self]);
    };
  };
}


<|start_filename|>lib/supports-animation/index.js<|end_filename|>
/**
 * Module dependencies.
 */

var _ = require('underscore');
var prefixes = ['Webkit', 'Moz', 'O', 'ms', 'Khtml', ''];
var animationEndNames = {
  'Animation':'animationend',
  'OAnimation':'oAnimationEnd',
  'MozAnimation':'animationend',
  'WebkitAnimation':'webkitAnimationEnd'
};

module.exports = function () {
  return _.chain(prefixes)
    .map(function (prefix) {
      return prefix + 'Animation';
    })
    .filter(function (s) {
      return typeof document.body.style[s] !== 'undefined';
    })
    .map(function (supportedAnimation) {
      return animationEndNames[supportedAnimation];
    })
    .first()
    .value();
};


<|start_filename|>i18n/tlh.json<|end_filename|>
{
  "//": "This is an automatic translation. Help us to improve it.",
  "loadingTitle": "DubelmoHchugh loS.",
  "close": "SoQmoH",
  "signin": {
    "title": "qI'",
    "action": "qI'",
    "all": "cha' Hoch",
    "strategyEmailEmpty": "chIm email.",
    "strategyEmailInvalid": "email invalid.",
    "strategyDomainInvalid": "{domain} yer wej setup.",
    "signupText": "qI'",
    "forgotText": "mu'wIj lIj?",
    "emailPlaceholder": "email",
    "usernamePlaceholder": "tus neeg siv lub npe",
    "passwordPlaceholder": "<PASSWORD>",
    "separatorText": "ghap",
    "serverErrorText": "Qagh qaStaHvIS qI' mIw tu'lu'.",
    "returnUserLabel": "Qav poH qI' SoH qaStaHvIS lo'.",
    "wrongEmailPasswordErrorText": "QIH email pagh mu'wIj.",
    "or": "... pagh qI' qaStaHvIS yIlo'",
    "loadingMessage": "Ukubhalisela In nge {connection}..."
  },
  "signup": {
    "description": "",
    "title": "qI'",
    "action": "qI'",
    "emailPlaceholder": "email",
    "passwordPlaceholder": "<PASSWORD>",
    "cancelAction": "qIl",
    "headerText": "nuqneH email mu'wIj je",
    "footerText": "",
    "enterpriseEmailWarningText": "configured {domain} yer Vas qI' 'ej account pagh chenmoH SoH. nID, qI' instead.",
    "serverErrorText": "Qagh qI' mIw Ha' tu'lu'."
  },
  "reset": {
    "title": "mu'wIj reset",
    "action": "ngeH",
    "emailPlaceholder": "email",
    "passwordPlaceholder": "<PASSWORD>'",
    "repeatPasswordPlaceholder": "mu'wIj chu' confirm",
    "cancelAction": "qIl",
    "successText": "jIboQqang reset mu'wIj neH ngeH SoH maH.",
    "enterSamePasswordText": "<PASSWORD> mu'wIj rap 'el.",
    "headerText": "nuqneH email chu' mu'wIj je. jIboQqang mu'wIj choH confirm ngeH SoH maH.",
    "serverErrorText": "Qagh reset mu'wIj mIw tu'lu'."
  }
}

<|start_filename|>example/build/index.css<|end_filename|>
body {
  font-family: "Helvetica Neue", "Lucida Grande", "Arial";
}
h1,
h2,
h3 {
  font-weight: 100;
  font-family: "Helvetica Neue", "Lucida Grande", "Arial";
}
.sidebar-box ul a {
  font-size: 13px;
  cursor: pointer;
}
pre {
  border: 0;
  padding: 20px;
  font-size: 12px;
}
header.site-header {
  padding: 20px 0 20px 0;
  left: 0;
  right: 0;
  top: 0;
  z-index: 1000;
  background: #fff;
  font-size: 14px;
}
@media screen and (max-width: 600px) {
  .sub-header ul.external-links {
    float: left;
  }
  .sub-header ul.external-links li {
    margin-left: 0;
    float: left;
    margin-top: 20px;
    margin-right: 20px;
  }
  .sidebar-box {
    max-width: 100%;
    background: #f1f1f1;
  }
}


<|start_filename|>test/options.tests.js<|end_filename|>
/**
 * Mocha config
 */

mocha.timeout(60000);
mocha.ui('bdd');
mocha.reporter('html');
mocha.globals(['jQuery*', '__auth0jp*', 'Auth0*']);

describe('_findConnectionByEmailDomain', function () {
  var domain = 'abc.auth0.com';
  var clientID = '123456789';
  var widget;

  before(function (done) {
    widget = new Auth0Lock(clientID, domain);
    widget.display();
    done();
  });

  after(function (done) {
    global.window.Auth0 = null;
    widget.hide(done);
  });

  it('should return connection when email domain matches `domain`', function() {
    var entry = {domain: 'bye.com'};
    var result = widget.options._findConnectionByDomain('bye.com', [
      { connections: [entry] }
    ]);

    expect(result).not.to.be(undefined);
    expect(result.domain).to.be.equal(entry.domain);
    expect(result.domains).to.be.ok;
    expect(result.domains.length).to.be.equal(1);
    expect(result.domains[0]).to.equal(entry.domain);
  });

  it('should return connection when email domain matches `domain_aliases`', function () {
    var entry = { domain: 'bye.com', domain_aliases: ['bye.com', 'foo.com', 'bar.com'] };
    var result = widget.options._findConnectionByDomain('bar.com', [
      { connections: [entry] }
    ]);

    expect(result).not.to.be(undefined);
    expect(result.domain).to.be.equal(entry.domain);
    expect(result.domain_aliases).to.eql(entry.domain_aliases);
    expect(result.domains).not.to.be(undefined);
    expect(result.domains.length).to.be.equal(4);
    expect(result.domains).to.contain(entry.domain);
  });

  it('should return connection when email domain matches `domain_aliases` on second connection entry', function () {
    var entry = {domain: 'bye.com', domain_aliases: ['bye.com', 'foo.com', 'bar.com']};
    var result = widget.options._findConnectionByDomain('bar.com', [
      { connections: [] }, { connections: [{ domain: 'foobar.com' }] }, { connections: [entry] }
    ]);
    expect(result).not.to.be(undefined);
    expect(result.domain).to.be.equal(entry.domain);
    expect(result.domain_aliases).to.eql(entry.domain_aliases);
    expect(result.domains).not.to.be(undefined);
    expect(result.domains.length).to.be.equal(4);
    expect(result.domains).to.contain(entry.domain);
  });

  it('should return falsy when email domain matches neither `domain` nor `domain_aliases`', function () {
    var entry = {domain: 'bye.com', domain_aliases: ['bye.com', 'foo.com', 'bar.com']};
    var result = widget.options._findConnectionByDomain('unknown.com', [
      { connections: [entry] }
    ]);

    expect(result).to.be(undefined);
  });
});


<|start_filename|>lib/mode-loading/index.js<|end_filename|>
/**
 * Module dependencies.
 */

var _ = require('underscore');
var $ = require('../bonzo-augmented');
var Emitter = require('events').EventEmitter;
var create = require('../object-create');
var template = require('./loading.ejs');

/**
 * Expose LoadingPanel
 */

module.exports = LoadingPanel;

/**
 * Create `LoadingPanel`
 *
 * @param {Auth0Lock} widget
 * @param {Object} options
 * @constructor
 */

function LoadingPanel(widget, options) {
  if (!(this instanceof LoadingPanel)) {
    return new LoadingPanel(widget, options);
  };

  // Both `widget` and `options` are required
  if (2 !== arguments.length) {
    throw new Error('Missing parameters for LoadingPanel');
  }

  this.name = 'loading';
  this.widget = widget;
  this.options = this.resolveOptions(options);
  this.el = null;

  Emitter.call(this);
}

/**
 * Inherit from `EventEmitter`
 */

LoadingPanel.prototype = create(Emitter.prototype);

/**
 * Query for elements at `this.el` context
 *
 * @param {String} selector
 * @return {BonzoAugmented}
 * @public
 */

LoadingPanel.prototype.query = function(selector) {
  if (!this.el) throw new Error('Can\'t get element since no `el` is set to local context');
  return $(selector, this.el);
}

/**
 * Create `el`
 *
 * @param {Object} options
 * @return {NodeElement}
 * @public
 */

LoadingPanel.prototype.create = function(options) {
  var opts = this.resolveOptions(options);
  var widget = this.widget;

  this.el = $.create(widget.render(template, opts))[0];
  this.bindAll();
  return this.el;
}

/**
 * Return `el` or create it
 *
 * @param {Object} options
 * @return {NodeElement}
 * @public
 */

LoadingPanel.prototype.render = function() {
  return null != this.el
    ? this.el
    : this.create.apply(this, arguments);
}

/**
 * Resolves login options passed to template
 *
 * @param {Object} options
 * @return {Object}
 * @private
 */

LoadingPanel.prototype.resolveOptions = function(options) {
  return _.extend({}, this.widget.options,  this.options, options);
}

/**
 * Bind events to `this.el`, like submit
 */

LoadingPanel.prototype.bindAll = function() {
  return this;
}


<|start_filename|>lib/assert-required/index.js<|end_filename|>
/**
 * Expose `required`
 */

module.exports = required;

/**
 * Assert `prop` as requirement at `obj`
 *
 * @param {Object} obj
 * @param {prop} prop
 * @public
 */

function required (prop, obj) {
  if (!obj[prop]) {
    throw new Error(prop + ' is required.');
  }
}


<|start_filename|>lib/mode-loggedin/index.js<|end_filename|>
/**
 * Module dependencies.
 */

var Emitter = require('events').EventEmitter;
var create = require('../object-create');
var template = require('./loggedin.ejs');
var loggedinBtnTmpl = require('./loggedin_button.ejs');
var stop = require('../stop-event');
var _ = require('underscore');
var $ = require('../bonzo-augmented');
var gravatar = require('../gravatar');

/**
 * Expose LoggedinPanel
 */

module.exports = LoggedinPanel;

/**
 * Create `LoggedinPanel`
 *
 * @param {Auth0Lock} widget
 * @param {Object} options
 * @constructor
 */

function LoggedinPanel(widget, options) {
  if (!(this instanceof LoggedinPanel)) {
    return new LoggedinPanel(widget, options);
  }

  // Both `widget` and `options` are required
  if (2 !== arguments.length) {
    throw new Error('Missing parameters for LoggedinPanel');
  }

  this.name = 'loggedin';
  this.widget = widget;
  this.options = this.resolveOptions(options);
  this.el = null;

  Emitter.call(this);
}

/**
 * Inherit from `EventEmitter`
 */

LoggedinPanel.prototype = create(Emitter.prototype);

/**
 * Query for elements at `this.el` context
 *
 * @param {String} selector
 * @return {BonzoAugmented}
 * @public
 */

LoggedinPanel.prototype.query = function(selector) {
  if (!this.el) { throw new Error('Can\'t get element since no `el` is set to local context'); }
  return $(selector, this.el);
};

/**
 * Create `el`
 *
 * @param {Object} options
 * @return {NodeElement}
 * @public
 */

LoggedinPanel.prototype.create = function(options) {
  var opts = this.resolveOptions(options);
  var widget = this.widget;

  this.el = $.create(widget.render(template, opts))[0];
  this.bindAll();
  return this.el;
};

/**
 * Return `el` or create it
 *
 * @param {Object} options
 * @return {NodeElement}
 * @public
 */

LoggedinPanel.prototype.render = function() {
  return null != this.el
    ? this.el
    : this.create.apply(this, arguments);
};

/**
 * Resolves login options passed to template
 *
 * @param {Object} options
 * @return {Object}
 * @private
 */

LoggedinPanel.prototype.resolveOptions = function(options) {
  return _.extend({}, this.widget.options,  this.options, options);
};

/**
 * Bind events to `this.el`, like submit
 */

LoggedinPanel.prototype.bindAll = function() {
  var self = this;
  var widget = this.widget;
  var options = this.options;

  var strategy_name = widget.$ssoData.lastUsedConnection.strategy;
  var strategy = widget.$strategies[strategy_name];

  if (!strategy) { return; }

  this.query('form').a0_on('submit', function (e) {
    stop(e);
    widget._signInEnterprise(e);
  });

  if (options.gravatar) {
    gravatar(this.widget, widget.$ssoData.lastUsedUsername);
  }


  var button = $.create(loggedinBtnTmpl({
    name: strategy_name,
    title: strategy.title,
    css: strategy.css,
    imageicon: strategy.imageicon,
    username: widget.$ssoData.lastUsedUsername
  }));

  this.query('.a0-last-time').html(options.i18n.t('signin:returnUserLabel'));

  this.query('.a0-strategy div').remove();

  this.query('.a0-strategy').append(button);

  this.query('.a0-strategy .a0-zocial[data-strategy]').a0_on('click', function (e) {
    stop(e);

    widget._signinSocial(
      strategy_name,
      widget.$ssoData.lastUsedConnection && widget.$ssoData.lastUsedConnection.name,
      options._getLoggedInAuthParams(strategy_name, widget.$ssoData),
      self
    );
  });

  this.query('.a0-all').a0_on('click', function (e) {
    stop(e);
    // no need to check other panels since
    // no reset nor signup modes allow for
    // return user experience...
    gravatar(widget, '');
    widget._signinPanel(self.options);
  });

};

LoggedinPanel.prototype.query = function(selector) {
  return $(selector, this.el);
};


<|start_filename|>i18n/nl-NL.json<|end_filename|>
{
  "//": "This is an automatic translation. Help us to improve it.",
  "loadingTitle": "Een ogenblik geduld...",
  "close": "Sluiten",
  "signin": {
    "title": "Aanmelden",
    "action": "Aanmelden",
    "all": "Toon alles",
    "strategyEmailEmpty": "Het veld e-mail is leeg.",
    "strategyEmailInvalid": "Het veld e-mail is ongeldig.",
    "strategyDomainInvalid": "Het domein {domain} is niet geactiveerd.",
    "signupText": "Aanmelden",
    "forgotText": "Wachtwoord vergeten?",
    "emailPlaceholder": "E-mail",
    "usernamePlaceholder": "Usernamea",
    "passwordPlaceholder": "<PASSWORD>",
    "separatorText": "of",
    "serverErrorText": "Er is een fout opgetreden tijdens het inloggen.",
    "returnUserLabel": "De laatste keer logde je in met...",
    "wrongEmailPasswordErrorText": "Verkeerd e-mail of wachtwoord.",
    "or": "... of meld u aan met",
    "loadingMessage": "Aanmelden met {connection}..."
  },
  "signup": {
    "description": "",
    "title": "Aanmelden",
    "action": "Aanmelden",
    "emailPlaceholder": "E-mail",
    "passwordPlaceholder": "<PASSWORD>",
    "cancelAction": "Annuleren",
    "headerText": "Voer je email en wachtwoord in",
    "footerText": "",
    "enterpriseEmailWarningText": "Dit domein {domain} is geconfigureerd voor eenmalige aanmelding en u kunt geen account aanmaken. Probeer u aan te melden in plaats daarvan.",
    "serverErrorText": "Er is een fout opgetreden bij de verwerking van uw aanmelding."
  },
  "reset": {
    "title": "Wachtwoord resetten",
    "action": "Verzenden",
    "emailPlaceholder": "E-mail",
    "passwordPlaceholder": "<PASSWORD>",
    "repeatPasswordPlaceholder": "Bevestig het nieuwe wachtwoord",
    "cancelAction": "Annuleren",
    "successText": "We hebben u zojuist een e-mail gestuurd om uw wachtwoord te resetten.",
    "enterSamePasswordText": "Voer hetzelfde wachtwoord in.",
    "headerText": "Voer uw e-mailadres en het nieuwe wachtwoord in. Wij sturen u een e-mail ter bevestiging van de wachtwoordswijziging.",
    "serverErrorText": "Er is een fout opgetreden bij de verwerking van het nieuwe wachtwoord."
  }
}


<|start_filename|>standalone.js<|end_filename|>
/*
 *
 * This is used to build the bundle with browserify.
 *
 * The bundle is used by people who doesn't use browserify.require
 * Those who use browserify will install with npm and require the module,
 * the package.json file points to index.js.
 */
var Auth0Lock = require('./');

// use amd or just throught to window object.
if (typeof global.window.define == 'function' && global.window.define.amd) {
  global.window.define('auth0-lock', function () { return Auth0Lock; });
} else if (global.window) {
  global.window.Auth0Lock = Auth0Lock;
}


<|start_filename|>test/support/config.js<|end_filename|>
/**
 * Mocha config
 */

mocha.timeout(60000);
mocha.ui('bdd');
mocha.reporter('html');
mocha.globals(['jQuery*', '__auth0jp*', 'Auth0*']);


<|start_filename|>lib/bind/index.js<|end_filename|>
/**
 * Expose `bind`
 */

module.exports = bind;

/**
 * Bind `fn` to `obj`
 */
function bind(fn, obj) {
  return function binded() {
    return fn.apply(obj, arguments);
  }
}


<|start_filename|>i18n/pt.json<|end_filename|>
{
  "//": "This is an automatic translation. Help us to improve it.",
  "loadingTitle": "Aguarde...",
  "close": "Fechar",
  "signin": {
    "title": "Entrar",
    "action": "Entrar",
    "all": "Mostrar todos",
    "strategyEmailEmpty": "O e-mail é vazio.",
    "strategyEmailInvalid": "O email é inválido.",
    "strategyDomainInvalid": "O domínio {domain} não foi a instalação.",
    "signupText": "Inscrição",
    "forgotText": "Esqueceu sua senha?",
    "emailPlaceholder": "Email",
    "usernamePlaceholder": "Nome de Usuário",
    "passwordPlaceholder": "<PASSWORD>",
    "separatorText": "ou",
    "serverErrorText": "Houve um erro ao processar o sinal em.",
    "returnUserLabel": "Da última vez que você assinou usando...",
    "wrongEmailPasswordErrorText": "Senha ou e-mail errado.",
    "or": "... ou Cadastre-se no uso de",
    "loadingMessage": "Entrar com {connection}..."
  },
  "signup": {
    "description": "",
    "title": "Inscrição",
    "action": "Inscrição",
    "emailPlaceholder": "Email",
    "passwordPlaceholder": "<PASSWORD>",
    "cancelAction": "Cancelar",
    "headerText": "Por favor, digite seu e-mail e senha",
    "footerText": "",
    "enterpriseEmailWarningText": "Este domínio {domain} tiver sido configurado para Sign-On único e você não pode criar uma conta. Tente entrar em vez disso.",
    "serverErrorText": "Houve um erro ao processar o sinal de cima."
  },
  "reset": {
    "title": "Redefinir senha",
    "action": "Enviar",
    "emailPlaceholder": "Email",
    "passwordPlaceholder": "<PASSWORD>",
    "repeatPasswordPlaceholder": "<PASSWORD>irmar nova senha",
    "cancelAction": "Cancelar",
    "successText": "Só te enviamos um e-mail para redefinir sua senha.",
    "enterSamePasswordText": "Por favor digite a mesma senha.",
    "headerText": "Por favor, digite seu e-mail e a senha nova. Nós lhe enviaremos um e-mail para confirmar a alteração de senha.",
    "serverErrorText": "Houve um erro ao processar a redefinir a senha."
  }
}

<|start_filename|>lib/gravatar/index.js<|end_filename|>
var md5 = require('blueimp-md5').md5;
var regex = require('../regex');
var trim = require('trim');

/**
 * Create gravatar url
 *
 * @private
 */
function createURL(parsedEmail) {
  // Trim leading and trailing whitespace
  parsedEmail = trim(parsedEmail);

  // Force all characters to lower-case
  parsedEmail = parsedEmail.toLowerCase();

  // Apply MD5
  // We are not using:
  //  var createHash = require('crypto').createHash;
  //  var md5sum = createHash('md5').update(parsedEmail);
  // As it does not work in IE9 :(

  return 'https://www.gravatar.com/avatar/' + md5(parsedEmail) + '?d=404';

}

/**
 * Sets the header image using a Gravatar asociated with a
 * given mail.
 *
 * @param {Object} widget
 * @param {String} mail
 *
 * @static
 * @public
 */
// TODO Change widget to header
module.exports = function (widget, mail) {
    var parseResult = regex.email_parser.exec(mail.toLowerCase());

    // valid email? Then fetch it in Gravatar
    if (parseResult) {
      var parsedEmail = parseResult[0];

      widget.setImage(createURL(parsedEmail));

    } else {
      widget.restoreImage();
    }
};



<|start_filename|>lib/supports-placeholder/index.js<|end_filename|>
function placeholderIsSupported() {
  var test = document.createElement('input');
  return ('placeholder' in test);
}

module.exports = placeholderIsSupported();

<|start_filename|>lib/utils/index.js<|end_filename|>
var _ = require('underscore');

module.exports = {
  parseUrl: function (url) {
    var parser = document.createElement('a');
    parser.href = url;
    return parser;
  },

  endsWith: function (str, suffix) {
    return str.indexOf(suffix, str.length - suffix.length) !== -1;
  },

  extract: function (obj, props) {
    var pre = _.pick(obj, props);

    return _.chain(_.pairs(pre))
            .filter(function (pair) {
              return typeof pair[1] !== 'undefined';
            }).reduce(function (r, current) {
              r[current[0]] = current[1];
              return r;
            }, {}).value();
  }
};
