<commit_before>Meteor.methods({
  'getAllResidentIds': function () {
    // TODO: determine how to secure this method to prevent client abuse

    // Get all residents
    var residents = Residents.find().fetch();

    // Create an array of resident IDs
    var residentIds = _.map(residents, function (resident) {
      return resident._id;
    });

    return residentIds;
  },
  'getCurrentResidentIds': function () {
    // TODO: determine how to secure this method to prevent client abuse

    // Get all residents
    var residents = Residents.find({departed: false}).fetch();

    // Create an array of resident IDs
    var residentIds = _.map(residents, function (resident) {
      return resident._id;
    });

    return residentIds;
  },
  'getResidentsNameHomeAndLatestActivityByType': function (activityTypeId) {
    // Get all resident IDs
    var residentIds = Meteor.call('getCurrentAllResidentIds');

    // Placeholder for residents latest activity
    var residentsLatestActivityByType = [];

    // Loop through all resident IDs
    residentIds.forEach(function (residentId) {
      // Return resident latest activity
      var residentLatestActivity = Meteor.call('getResidentLatestActivityByType', residentId, activityTypeId);

      // If resident activity exists
      if (residentLatestActivity !== undefined) {
        // Get resident from collection
        var resident = Residents.findOne(residentId);

        // Construct an object with resident name and last activity date
        var residentActivityObject = {
          residentName: resident.fullName(),
          homeName: resident.homeName(),
          activityDate: residentLatestActivity.activityDate
        };

        // Add resident latest activity to residents latest activity array
        residentsLatestActivityByType.push(residentActivityObject);
      }
    });

    return residentsLatestActivityByType;
  },
  'getResidentsWithoutActivityByType': function (activityTypeId) {
    // // Get resident latest activity by type
    // var residentLastActivityByType = Meteor.call('getResidentsLatestActivityByType', activityTypeId);
    //
    // // Get all resident IDs
    // var residentIds = Residents.find({}, {fields: {_id: 1}}).fetch();
    //
    // // Get residents who have participated in the activity type
    // var residentsWithPreviousActivity = _.map(residentLastActivityByType, function (resident) {
    //   return resident._id;
    // });
    //
    // // Get residents who have not participated in activity type
    // var residentsWithoutPreviousActivity = _.difference(residentIds, residentsWithPreviousActivity);
    //
    // return residentsWithoutPreviousActivity;
  },
  'getResidentRecentActivities': function (residentId) {
    // Date two weeks ago
    var twoWeeksAgo = moment().subtract(2, "weeks").toDate();

    // Date today
    var now = new Date();

    // Get all activities involving resident
    // make sure activities are in the past (i.e. not planned)
    //  sort in reverse order by activity date
    return Activities.find({'residentIds': residentId, activityDate: {$gte: twoWeeksAgo, $lte: now}}, {sort : {activityDate:  -1} });
  },
  'getResidentActivitiesByTypeLast30Days': function (residentId, activityTypeId) {
    // Date thirty days ago
    var thirtyDaysAgo = moment().subtract(30, "days").toDate();

    // Date today
    var now = new Date();

    // Get all activities of a specific type involving resident
    // make sure activities are in the past (i.e. not planned)
    //  sort in reverse order by activity date
    var activities = Activities.find({
      'residentIds': residentId,
      'activityTypeId': activityTypeId,
      activityDate: {$gte: thirtyDaysAgo, $lte: now}},
      {sort : {activityDate:  -1}
    }).fetch();

    if (activities) {
      return activities;
    };
  },
  'getSumOfResidentActivitiesByTypeLast30Days': function (residentId, activityTypeId) {
    var activities = Meteor.call('getResidentActivitiesByTypeLast30Days', residentId, activityTypeId);

    // Placeholder for sum of activities
    var sumOfActivities = 0;

    if (activities) {
      // Count each activity
      activities.forEach(function (activity) {
        // Count the resident activity
        sumOfActivities += 1;
      });
    };

    return sumOfActivities;
  },
  'getSumOfAllResidentRecentActivitiesByType': function (residentId) {
    // Get all activity type IDs
    var activityTypeIds = Meteor.call('getAllActivityTypeIds');

    // Placeholder for resident activity sums
    var residentActivitySumsByType = [];

    activityTypeIds.forEach(function (activityTypeId) {
      // Get the activity type
      var activityType = ActivityTypes.findOne(activityTypeId);

      // Get the resident
      var resident = Residents.findOne(residentId);

      // Get sum of activity type for the current resident
      var activitySum = Meteor.call('getSumOfResidentRecentActivitiesByType', residentId, activityTypeId);

      // Create an object with the activity type name and sum
      var activityTypeSum = {
        residentName: resident.fullName(),
        activityTypeName: activityType.name,
        sum: activitySum
      }

      // Add the resident activity type sum to the resident activity sums array
      residentActivitySumsByType.push(activityTypeSum);
    });

    return residentActivitySumsByType;
  },
  'getAllResidentsActivitySumsByType': function () {
    // Get all resident IDs
    var residentIds = Meteor.call('getCurrentResidentIds');

    // Placeholder for all resident activity sums by type
    var allResidentActivitySumsByType = [];

    // Iterate through all residents and get sum of resident recent activities by type
    residentIds.forEach(function (residentId) {
      // Get the sum of all activities by type for a given resident
       var residentActivitiesSumByType = Meteor.call('getSumOfAllResidentRecentActivitiesByType', residentId);

      // Add the resident activity sums to all resident activity sums array
      allResidentActivitySumsByType.push(residentActivitiesSumByType);
    });

    allResidentActivitySumsByTypeFlattened = _.flatten(allResidentActivitySumsByType)

    return allResidentActivitySumsByTypeFlattened;
  }
});
<commit_msg>Cleanup<commit_after>Meteor.methods({
  'getAllResidentIds': function () {
    // TODO: determine how to secure this method to prevent client abuse

    // Get all residents
    var residents = Residents.find().fetch();

    // Create an array of resident IDs
    var residentIds = _.map(residents, function (resident) {
      return resident._id;
    });

    return residentIds;
  },
  'getCurrentResidentIds': function () {
    // TODO: determine how to secure this method to prevent client abuse

    // Get all residents
    var residents = Residents.find({departed: false}).fetch();

    // Create an array of resident IDs
    var residentIds = _.map(residents, function (resident) {
      return resident._id;
    });

    return residentIds;
  },
  'getResidentsNameHomeAndLatestActivityByType': function (activityTypeId) {
    // Get all resident IDs
    var residentIds = Meteor.call('getCurrentAllResidentIds');

    // Placeholder for residents latest activity
    var residentsLatestActivityByType = [];

    // Loop through all resident IDs
    residentIds.forEach(function (residentId) {
      // Return resident latest activity
      var residentLatestActivity = Meteor.call('getResidentLatestActivityByType', residentId, activityTypeId);

      // If resident activity exists
      if (residentLatestActivity !== undefined) {
        // Get resident from collection
        var resident = Residents.findOne(residentId);

        // Construct an object with resident name and last activity date
        var residentActivityObject = {
          residentName: resident.fullName(),
          homeName: resident.homeName(),
          activityDate: residentLatestActivity.activityDate
        };

        // Add resident latest activity to residents latest activity array
        residentsLatestActivityByType.push(residentActivityObject);
      }
    });

    return residentsLatestActivityByType;
  },
  'getResidentRecentActivities': function (residentId) {
    // Date two weeks ago
    var twoWeeksAgo = moment().subtract(2, "weeks").toDate();

    // Date today
    var now = new Date();

    // Get all activities involving resident
    // make sure activities are in the past (i.e. not planned)
    //  sort in reverse order by activity date
    return Activities.find({'residentIds': residentId, activityDate: {$gte: twoWeeksAgo, $lte: now}}, {sort : {activityDate:  -1} });
  },
  'getResidentActivitiesByTypeLast30Days': function (residentId, activityTypeId) {
    // Date thirty days ago
    var thirtyDaysAgo = moment().subtract(30, "days").toDate();

    // Date today
    var now = new Date();

    // Get all activities of a specific type involving resident
    // make sure activities are in the past (i.e. not planned)
    //  sort in reverse order by activity date
    var activities = Activities.find({
      'residentIds': residentId,
      'activityTypeId': activityTypeId,
      activityDate: {$gte: thirtyDaysAgo, $lte: now}},
      {sort : {activityDate:  -1}
    }).fetch();

    if (activities) {
      return activities;
    };
  },
  'getSumOfResidentActivitiesByTypeLast30Days': function (residentId, activityTypeId) {
    var activities = Meteor.call('getResidentActivitiesByTypeLast30Days', residentId, activityTypeId);

    // Placeholder for sum of activities
    var sumOfActivities = 0;

    if (activities) {
      // Count each activity
      activities.forEach(function (activity) {
        // Count the resident activity
        sumOfActivities += 1;
      });
    };

    return sumOfActivities;
  },
  'getSumOfAllResidentRecentActivitiesByType': function (residentId) {
    // Get all activity type IDs
    var activityTypeIds = Meteor.call('getAllActivityTypeIds');

    // Placeholder for resident activity sums
    var residentActivitySumsByType = [];

    activityTypeIds.forEach(function (activityTypeId) {
      // Get the activity type
      var activityType = ActivityTypes.findOne(activityTypeId);

      // Get the resident
      var resident = Residents.findOne(residentId);

      // Get sum of activity type for the current resident
      var activitySum = Meteor.call('getSumOfResidentRecentActivitiesByType', residentId, activityTypeId);

      // Create an object with the activity type name and sum
      var activityTypeSum = {
        residentName: resident.fullName(),
        activityTypeName: activityType.name,
        sum: activitySum
      }

      // Add the resident activity type sum to the resident activity sums array
      residentActivitySumsByType.push(activityTypeSum);
    });

    return residentActivitySumsByType;
  },
  'getAllResidentsActivitySumsByType': function () {
    // Get all resident IDs
    var residentIds = Meteor.call('getCurrentResidentIds');

    // Placeholder for all resident activity sums by type
    var allResidentActivitySumsByType = [];

    // Iterate through all residents and get sum of resident recent activities by type
    residentIds.forEach(function (residentId) {
      // Get the sum of all activities by type for a given resident
       var residentActivitiesSumByType = Meteor.call('getSumOfAllResidentRecentActivitiesByType', residentId);

      // Add the resident activity sums to all resident activity sums array
      allResidentActivitySumsByType.push(residentActivitiesSumByType);
    });

    allResidentActivitySumsByTypeFlattened = _.flatten(allResidentActivitySumsByType)

    return allResidentActivitySumsByTypeFlattened;
  }
});
<|endoftext|>


<commit_before>'use strict';

/**
 * ButtressJS - Realtime datastore for business software
 *
 * @file user.js
 * @description User model definition.
 * @module Model
 * @exports model, schema, constants
 * @author Chris Bates-Keegan
 *
 */

const mongoose = require('mongoose');
const Model = require('../');
const Logging = require('../../logging');
const Shared = require('../shared');
const ObjectId = require('mongodb').ObjectId;

const collectionName = 'users';
const collection = Model.mongoDb.collection(collectionName);

/**
 * Constants
*/

const constants = {
};

Model.initModel('Person');
Model.initModel('Appauth');
// Model.Schema.Person;

/**
 * Schema
 */
const schema = new mongoose.Schema();
schema.add({
  username: String,
  orgRole: String,
  teamName: String,
  teamRole: String,
  metadata: [{
    _app: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'Application'
    },
    key: String,
    value: String
  }],
  _apps: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'Application'
    }
  ],
  _person: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Person'
  },
  _tokens: [{
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Token'
  }],
  auth: [Model.Schema.Appauth]
});

let ModelDef = null;

/**
 * Schema Virtual Methods
 */
schema.virtual('details').get(function() {
  return {
    id: this._id,
    username: this.username,
    orgRole: this.orgRole,
    teamName: this.teamName,
    teamRole: this.teamRole,
    auth: this.auth.map(a => a.details),
    person: this.tryPerson
  };
});

schema.virtual('authenticatedMetadata').get(function() {
  if (!this.metadata) {
    return [];
  }
  return this.metadata
    .filter(m => `${m._app}` === Model.authApp.id)
    .map(m => ({key: m.key, value: JSON.parse(m.value)}));
});

schema.virtual('tryPerson').get(function() {
  if (!this._person) {
    return false;
  }
  return this._person.details ? this._person.details : this._person;
});

/**
 * Schema Static Methods
 */

/**
 * @param {Object} body - body passed through from a POST request
 * @param {Object} personDetails - details of the person to which the user is attached
 * @param {Object} auth - OPTIONAL authentication details for a user token
 * @return {Promise} - returns a promise that is fulfilled when the database request is completed
 */
schema.statics.add = (body, personDetails, auth) => {
  var user = new ModelDef({
    _apps: [Model.authApp],
    _person: personDetails.id,
    orgRole: body.orgRole,
    teamName: body.teamName,
    teamRole: body.teamRole
  });

  // Logging.logDebug(body);
  // Logging.logDebug(auth);

  user.auth.push(new Model.Appauth({
    // _id: body.id,
    app: body.app,
    appId: body.id,
    username: body.username,
    profileUrl: body.profileUrl,
    images: {
      profile: body.profileImgUrl,
      banner: body.bannerImgUrl
    },
    email: body.email,
    token: body.token,
    tokenSecret: body.tokenSecret
  }));

  Logging.logDebug(personDetails.name);
  Logging.logDebug(user.auth[0].app);
  Logging.logDebug(user.auth[0].appId);

  let saveUser = user.save().then(u => Object.assign(u.details, {person: personDetails}));
  let getToken = auth ? Model.Token.add(Object.assign(auth, {user: user})) : Promise.resolve(null);

  return Promise.all([saveUser, getToken]);
};

schema.methods.addAuth = function(auth) {
  Logging.log(`addAuth: ${auth.app}`, Logging.Constants.LogLevel.INFO);
  let existing = this.auth.find(a => a.app === auth.app && a.id == auth.id); // eslint-disable-line eqeqeq
  if (existing) {
    Logging.log(`present: ${auth.app}:${auth.id}`, Logging.Constants.LogLevel.DEBUG);
    return Promise.resolve(this);
  }

  Logging.log(`not present: ${auth.app}:${auth.id}`, Logging.Constants.LogLevel.DEBUG);
  this.auth.push(new Model.Appauth({
    app: auth.app,
    appId: auth.id,
    username: auth.username,
    profileUrl: auth.profileUrl,
    images: {
      profile: auth.profileImgUrl,
      banner: auth.bannerImgUrl
    },
    email: auth.email,
    token: auth.token,
    tokenSecret: auth.tokenSecret,
    refreshToken: auth.refreshToken
  }));
  return this.save();
};

/**
 * @param {string} app - name of the app for which the token is being updated
 * @param {Object} updated - updated app information passed through from a PUT request
 * @return {Promise} - returns a promise that is fulfilled when the database request is completed
 */
schema.methods.updateAppInfo = function(app, updated) {
  var auth = this.auth.find(a => a.app === app);
  if (!auth) {
    Logging.log(`Unable to find Appauth for ${app}`, Logging.Constants.LogLevel.DEBUG);
    return Promise.resolve(false);
  }

  auth.username = updated.username;
  auth.profileUrl = updated.profileUrl;
  auth.images.profile = updated.profileImgUrl;
  auth.images.banner = updated.bannerImgUrl;
  auth.email = updated.email;
  auth.token = updated.token;
  auth.tokenSecret = updated.tokenSecret;
  auth.refreshToken = updated.refreshToken;

  Logging.logDebug(updated.profileImgUrl);

  return this.save().then(() => true);
};

schema.methods.updateApps = function(app) {
  Logging.log(`updateApps: ${Model.authApp._id}`, Logging.Constants.LogLevel.INFO);
  if (!this._apps) {
    this._apps = [];
  }
  let matches = this._apps.filter(function(a) {
    return a._id === app._id;
  });
  if (matches.length > 0) {
    Logging.log(`present: ${Model.authApp._id}`, Logging.Constants.LogLevel.DEBUG);
    return Promise.resolve();
  }

  Logging.log(`not present: ${Model.authApp._id}`, Logging.Constants.LogLevel.DEBUG);
  this._apps.push(app._id);
  return this.save();
};

schema.statics.exists = id => {
  return collection.find({_id: new ObjectId(id)})
    .limit(1)
    .count()
    .then(count => count > 0);
};

/**
 * @return {Promise} - resolves once all have been deleted
 */
schema.statics.rmAll = () => {
  return ModelDef.remove({});
};

/**
 * @param {Object} user - User object to remove
 * @return {Promise} - returns a promise that is fulfilled when the database request is completed
 */
schema.statics.rm = function(user) {
  return ModelDef.remove({_id: user._id});
};

/**
 * @param {ObjectId} appId - id of the App that owns the user
 * @return {Promise} - resolves to an array of Apps (native Mongoose objects)
 */
schema.statics.getAll = () => {
  Logging.logSilly(`getAll: ${Model.authApp._id}`);

  if (Model.token.authLevel === Model.Constants.Token.AuthLevel.SUPER) {
    return ModelDef.find({});
  }

  return ModelDef.find({_apps: Model.authApp._id}).populate('_person');
};

/**
 * @return {Promise} - resolves to an array of Apps (native Mongoose objects)
 */
schema.statics.getSimplified = () => {
  Logging.logSilly(`getSimplified: ${Model.authApp._id}`);
  return collection.find({_apps: Model.authApp._id}, {_id: 1});
};

/**
 * @param {string} username - username to check for
 * @return {Promise} - resolves to a User object or null
 */
schema.statics.getByUsername = username => {
  return ModelDef.findOne({username: username}).select('id');
};

/**
 * @param {string} appName - Name of the authenticating App (facebook|twitter|google) that owns the user
 * @param {string} appUserId - AppId of the user
 * @return {Promise} - resolves to an array of Apps (native Mongoose objects)
 */
schema.statics.getByAppId = (appName, appUserId) => {
  Logging.log(`getByAppId: ${appName} - ${appUserId}`, Logging.Constants.LogLevel.VERBOSE);

  return ModelDef.findOne({'auth.app': appName, 'auth.appId': appUserId}).select('id');
};

schema.methods.attachToPerson = function(person, details) {
  if (person !== null) {
    this._person = person;
    return this.save();
  }

  return new Promise((resolve, reject) => {
    Model.Person
      .add(details, Model.authApp._owner)
      .then(person => {
        Logging.log(person, Logging.Constants.LogLevel.DEBUG);
        this._person = person.id;
        return this.save();
      })
      .then(resolve, reject);
  });
};

/**
 * @param {string} app - name of the app for which the token is being updated
 * @param {Object} body - body passed through from a PUT request
 * @return {Promise} - returns a promise that is fulfilled when the database request is completed
 */
schema.methods.updateToken = function(app, body) {
  var auth = this.auth.find(a => a.app === app);
  if (!auth) {
    Logging.log(`Unable to find Appauth for ${app}`, Logging.Constants.LogLevel.DEBUG);
    return Promise.resolve(false);
  }

  Logging.log(`Old Token: ${auth.token}`, Logging.Constants.LogLevel.DEBUG);
  Logging.log(`Old Token Secret: ${auth.tokenSecret}`, Logging.Constants.LogLevel.DEBUG);
  Logging.log(`New Token: ${body.token}`, Logging.Constants.LogLevel.DEBUG);
  Logging.log(`New Token Secret: ${body.tokenSecret}`, Logging.Constants.LogLevel.DEBUG);

  auth.token = body.token;
  auth.tokenSecret = body.tokenSecret;

  return this.save().then(() => true);
};

/**
 * @param {string} key - index name of the metadata
 * @param {*} value - value of the meta data
 * @return {Promise} - resolves when save operation is completed, rejects if metadata already exists
 */
schema.methods.addOrUpdateMetadata = function(key, value) {
  Logging.log(`${Model.authApp.id}`, Logging.Constants.LogLevel.DEBUG);
  Logging.log(key, Logging.Constants.LogLevel.DEBUG);
  Logging.log(value, Logging.Constants.LogLevel.DEBUG);

  var exists = this.metadata.find(m => `${m._app}` === Model.authApp.id && m.key === key);
  if (exists) {
    exists.value = value;
  } else {
    this.metadata.push({_app: Model.authApp, key: key, value: value});
  }

  return this.save().then(u => ({key: key, value: JSON.parse(value)}));
};

schema.methods.findMetadata = function(key) {
  Logging.log(`findMetadata: ${key}`, Logging.Constants.LogLevel.VERBOSE);
  Logging.log(this.metadata.map(m => ({app: `${m._app}`, key: m.key, value: m.value})),
              Logging.Constants.LogLevel.DEBUG);
  var md = this.metadata.find(m => `${m._app}` === `${Model.authApp._id}` && m.key === key);
  return md ? {key: md.key, value: JSON.parse(md.value)} : false;
};

/* ********************************************************************************
 *
 * UPDATE BY PATH
 *
 **********************************************************************************/

const PATH_CONTEXT = {
  '^(teamRole|teamName|orgRole)$': {type: 'scalar', values: []}
};

schema.statics.validateUpdate = Shared.validateUpdate(PATH_CONTEXT, collectionName);
schema.statics.updateByPath = Shared.updateByPath(PATH_CONTEXT, collectionName, collection);

ModelDef = mongoose.model('User', schema);

/**
 * Exports
 */
module.exports.constants = constants;
module.exports.schema = schema;
module.exports.model = ModelDef;
<commit_msg>LINT: removed blank line<commit_after>'use strict';

/**
 * ButtressJS - Realtime datastore for business software
 *
 * @file user.js
 * @description User model definition.
 * @module Model
 * @exports model, schema, constants
 * @author Chris Bates-Keegan
 *
 */

const mongoose = require('mongoose');
const Model = require('../');
const Logging = require('../../logging');
const Shared = require('../shared');
const ObjectId = require('mongodb').ObjectId;

const collectionName = 'users';
const collection = Model.mongoDb.collection(collectionName);

/**
 * Constants
*/

const constants = {
};

Model.initModel('Person');
Model.initModel('Appauth');
// Model.Schema.Person;

/**
 * Schema
 */
const schema = new mongoose.Schema();
schema.add({
  username: String,
  orgRole: String,
  teamName: String,
  teamRole: String,
  metadata: [{
    _app: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'Application'
    },
    key: String,
    value: String
  }],
  _apps: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'Application'
    }
  ],
  _person: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Person'
  },
  _tokens: [{
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Token'
  }],
  auth: [Model.Schema.Appauth]
});

let ModelDef = null;

/**
 * Schema Virtual Methods
 */
schema.virtual('details').get(function() {
  return {
    id: this._id,
    username: this.username,
    orgRole: this.orgRole,
    teamName: this.teamName,
    teamRole: this.teamRole,
    auth: this.auth.map(a => a.details),
    person: this.tryPerson
  };
});

schema.virtual('authenticatedMetadata').get(function() {
  if (!this.metadata) {
    return [];
  }
  return this.metadata
    .filter(m => `${m._app}` === Model.authApp.id)
    .map(m => ({key: m.key, value: JSON.parse(m.value)}));
});

schema.virtual('tryPerson').get(function() {
  if (!this._person) {
    return false;
  }
  return this._person.details ? this._person.details : this._person;
});

/**
 * Schema Static Methods
 */

/**
 * @param {Object} body - body passed through from a POST request
 * @param {Object} personDetails - details of the person to which the user is attached
 * @param {Object} auth - OPTIONAL authentication details for a user token
 * @return {Promise} - returns a promise that is fulfilled when the database request is completed
 */
schema.statics.add = (body, personDetails, auth) => {
  var user = new ModelDef({
    _apps: [Model.authApp],
    _person: personDetails.id,
    orgRole: body.orgRole,
    teamName: body.teamName,
    teamRole: body.teamRole
  });

  // Logging.logDebug(body);
  // Logging.logDebug(auth);

  user.auth.push(new Model.Appauth({
    // _id: body.id,
    app: body.app,
    appId: body.id,
    username: body.username,
    profileUrl: body.profileUrl,
    images: {
      profile: body.profileImgUrl,
      banner: body.bannerImgUrl
    },
    email: body.email,
    token: body.token,
    tokenSecret: body.tokenSecret
  }));

  Logging.logDebug(personDetails.name);
  Logging.logDebug(user.auth[0].app);
  Logging.logDebug(user.auth[0].appId);

  let saveUser = user.save().then(u => Object.assign(u.details, {person: personDetails}));
  let getToken = auth ? Model.Token.add(Object.assign(auth, {user: user})) : Promise.resolve(null);

  return Promise.all([saveUser, getToken]);
};

schema.methods.addAuth = function(auth) {
  Logging.log(`addAuth: ${auth.app}`, Logging.Constants.LogLevel.INFO);
  let existing = this.auth.find(a => a.app === auth.app && a.id == auth.id); // eslint-disable-line eqeqeq
  if (existing) {
    Logging.log(`present: ${auth.app}:${auth.id}`, Logging.Constants.LogLevel.DEBUG);
    return Promise.resolve(this);
  }

  Logging.log(`not present: ${auth.app}:${auth.id}`, Logging.Constants.LogLevel.DEBUG);
  this.auth.push(new Model.Appauth({
    app: auth.app,
    appId: auth.id,
    username: auth.username,
    profileUrl: auth.profileUrl,
    images: {
      profile: auth.profileImgUrl,
      banner: auth.bannerImgUrl
    },
    email: auth.email,
    token: auth.token,
    tokenSecret: auth.tokenSecret,
    refreshToken: auth.refreshToken
  }));
  return this.save();
};

/**
 * @param {string} app - name of the app for which the token is being updated
 * @param {Object} updated - updated app information passed through from a PUT request
 * @return {Promise} - returns a promise that is fulfilled when the database request is completed
 */
schema.methods.updateAppInfo = function(app, updated) {
  var auth = this.auth.find(a => a.app === app);
  if (!auth) {
    Logging.log(`Unable to find Appauth for ${app}`, Logging.Constants.LogLevel.DEBUG);
    return Promise.resolve(false);
  }

  auth.username = updated.username;
  auth.profileUrl = updated.profileUrl;
  auth.images.profile = updated.profileImgUrl;
  auth.images.banner = updated.bannerImgUrl;
  auth.email = updated.email;
  auth.token = updated.token;
  auth.tokenSecret = updated.tokenSecret;
  auth.refreshToken = updated.refreshToken;

  Logging.logDebug(updated.profileImgUrl);

  return this.save().then(() => true);
};

schema.methods.updateApps = function(app) {
  Logging.log(`updateApps: ${Model.authApp._id}`, Logging.Constants.LogLevel.INFO);
  if (!this._apps) {
    this._apps = [];
  }
  let matches = this._apps.filter(function(a) {
    return a._id === app._id;
  });
  if (matches.length > 0) {
    Logging.log(`present: ${Model.authApp._id}`, Logging.Constants.LogLevel.DEBUG);
    return Promise.resolve();
  }

  Logging.log(`not present: ${Model.authApp._id}`, Logging.Constants.LogLevel.DEBUG);
  this._apps.push(app._id);
  return this.save();
};

schema.statics.exists = id => {
  return collection.find({_id: new ObjectId(id)})
    .limit(1)
    .count()
    .then(count => count > 0);
};

/**
 * @return {Promise} - resolves once all have been deleted
 */
schema.statics.rmAll = () => {
  return ModelDef.remove({});
};

/**
 * @param {Object} user - User object to remove
 * @return {Promise} - returns a promise that is fulfilled when the database request is completed
 */
schema.statics.rm = function(user) {
  return ModelDef.remove({_id: user._id});
};

/**
 * @param {ObjectId} appId - id of the App that owns the user
 * @return {Promise} - resolves to an array of Apps (native Mongoose objects)
 */
schema.statics.getAll = () => {
  Logging.logSilly(`getAll: ${Model.authApp._id}`);

  if (Model.token.authLevel === Model.Constants.Token.AuthLevel.SUPER) {
    return ModelDef.find({});
  }

  return ModelDef.find({_apps: Model.authApp._id}).populate('_person');
};

/**
 * @return {Promise} - resolves to an array of Apps (native Mongoose objects)
 */
schema.statics.getSimplified = () => {
  Logging.logSilly(`getSimplified: ${Model.authApp._id}`);
  return collection.find({_apps: Model.authApp._id}, {_id: 1});
};

/**
 * @param {string} username - username to check for
 * @return {Promise} - resolves to a User object or null
 */
schema.statics.getByUsername = username => {
  return ModelDef.findOne({username: username}).select('id');
};

/**
 * @param {string} appName - Name of the authenticating App (facebook|twitter|google) that owns the user
 * @param {string} appUserId - AppId of the user
 * @return {Promise} - resolves to an array of Apps (native Mongoose objects)
 */
schema.statics.getByAppId = (appName, appUserId) => {
  Logging.log(`getByAppId: ${appName} - ${appUserId}`, Logging.Constants.LogLevel.VERBOSE);

  return ModelDef.findOne({'auth.app': appName, 'auth.appId': appUserId}).select('id');
};

schema.methods.attachToPerson = function(person, details) {
  if (person !== null) {
    this._person = person;
    return this.save();
  }

  return new Promise((resolve, reject) => {
    Model.Person
      .add(details, Model.authApp._owner)
      .then(person => {
        Logging.log(person, Logging.Constants.LogLevel.DEBUG);
        this._person = person.id;
        return this.save();
      })
      .then(resolve, reject);
  });
};

/**
 * @param {string} app - name of the app for which the token is being updated
 * @param {Object} body - body passed through from a PUT request
 * @return {Promise} - returns a promise that is fulfilled when the database request is completed
 */
schema.methods.updateToken = function(app, body) {
  var auth = this.auth.find(a => a.app === app);
  if (!auth) {
    Logging.log(`Unable to find Appauth for ${app}`, Logging.Constants.LogLevel.DEBUG);
    return Promise.resolve(false);
  }

  Logging.log(`Old Token: ${auth.token}`, Logging.Constants.LogLevel.DEBUG);
  Logging.log(`Old Token Secret: ${auth.tokenSecret}`, Logging.Constants.LogLevel.DEBUG);
  Logging.log(`New Token: ${body.token}`, Logging.Constants.LogLevel.DEBUG);
  Logging.log(`New Token Secret: ${body.tokenSecret}`, Logging.Constants.LogLevel.DEBUG);

  auth.token = body.token;
  auth.tokenSecret = body.tokenSecret;

  return this.save().then(() => true);
};

/**
 * @param {string} key - index name of the metadata
 * @param {*} value - value of the meta data
 * @return {Promise} - resolves when save operation is completed, rejects if metadata already exists
 */
schema.methods.addOrUpdateMetadata = function(key, value) {
  Logging.log(`${Model.authApp.id}`, Logging.Constants.LogLevel.DEBUG);
  Logging.log(key, Logging.Constants.LogLevel.DEBUG);
  Logging.log(value, Logging.Constants.LogLevel.DEBUG);

  var exists = this.metadata.find(m => `${m._app}` === Model.authApp.id && m.key === key);
  if (exists) {
    exists.value = value;
  } else {
    this.metadata.push({_app: Model.authApp, key: key, value: value});
  }

  return this.save().then(u => ({key: key, value: JSON.parse(value)}));
};

schema.methods.findMetadata = function(key) {
  Logging.log(`findMetadata: ${key}`, Logging.Constants.LogLevel.VERBOSE);
  Logging.log(this.metadata.map(m => ({app: `${m._app}`, key: m.key, value: m.value})),
              Logging.Constants.LogLevel.DEBUG);
  var md = this.metadata.find(m => `${m._app}` === `${Model.authApp._id}` && m.key === key);
  return md ? {key: md.key, value: JSON.parse(md.value)} : false;
};

/* ********************************************************************************
 *
 * UPDATE BY PATH
 *
 **********************************************************************************/

const PATH_CONTEXT = {
  '^(teamRole|teamName|orgRole)$': {type: 'scalar', values: []}
};

schema.statics.validateUpdate = Shared.validateUpdate(PATH_CONTEXT, collectionName);
schema.statics.updateByPath = Shared.updateByPath(PATH_CONTEXT, collectionName, collection);

ModelDef = mongoose.model('User', schema);

/**
 * Exports
 */
module.exports.constants = constants;
module.exports.schema = schema;
module.exports.model = ModelDef;
<|endoftext|>


<commit_before>// Firefox user.js

// -----------------------------------------------------------------------------
// Startup
// -----------------------------------------------------------------------------

// Show a blank page when opening homepage and new window.
user_pref("browser.startup.page", 0);
user_pref("browser.startup.homepage", "about:blank");
user_pref("browser.startup.homepage_override.mstone", "ignore");

// Show a blank page when opening new tab.
user_pref("browser.newtabpage.enabled", false);
user_pref("browser.newtab.preload", false);

// Disable Activity Stream.
user_pref("browser.newtabpage.activity-stream.default.sites", "");
user_pref("browser.newtabpage.activity-stream.feeds.discoverystreamfeed", false);
user_pref("browser.newtabpage.activity-stream.feeds.section.highlights", false);
user_pref("browser.newtabpage.activity-stream.feeds.section.topstories", false);
user_pref("browser.newtabpage.activity-stream.feeds.snippets", false);
user_pref("browser.newtabpage.activity-stream.feeds.telemetry", false);
user_pref("browser.newtabpage.activity-stream.feeds.topsites", false);
user_pref("browser.newtabpage.activity-stream.showSearch", false);
user_pref("browser.newtabpage.activity-stream.showSponsored", false);
user_pref("browser.newtabpage.activity-stream.telemetry", false);

// -----------------------------------------------------------------------------
// Localization
// -----------------------------------------------------------------------------

// Set preferred language for displaying pages.
user_pref("intl.accept_languages", "ja,zh-tw,zh,en-us,en");

// Disable region updates.
user_pref("browser.region.update.enabled", false);
user_pref("browser.region.network.url", "");

// -----------------------------------------------------------------------------
// Content
// -----------------------------------------------------------------------------

// Set the minimum font size.
user_pref("font.minimum-size.ja", 10);
user_pref("font.minimum-size.ko", 10);
user_pref("font.minimum-size.zh-CN", 10);
user_pref("font.minimum-size.zh-HK", 10);
user_pref("font.minimum-size.zh-TW", 10);

// Disable WebRTC.
user_pref("media.peerconnection.enabled", false);
user_pref("media.peerconnection.ice.default_address_only", true);
user_pref("media.peerconnection.ice.no_host", true);
user_pref("media.peerconnection.ice.proxy_only_if_behind_proxy", true);

// Disable media device enumeration.
user_pref("media.navigator.enabled", false);

// Block all audio and video autoplay.
user_pref("media.autoplay.default", 5);
user_pref("media.autoplay.blocking_policy", 0);

// Block new requests asking for permissions.
user_pref("permissions.default.geo", 2);
user_pref("permissions.default.camera", 2);
user_pref("permissions.default.microphone", 2);
user_pref("permissions.default.desktop-notification", 2);
user_pref("permissions.default.xr", 2);
user_pref("permissions.default.shortcuts", 2);

// Block pop-up windows.
user_pref("dom.disable_open_during_load", true);
user_pref("dom.popup_allowed_events", "click dblclick mousedown mouseup pointerdown pointerup");

// Enforce all links to be opened in new tabs.
user_pref("browser.link.open_newwindow", 3);
user_pref("browser.link.open_newwindow.restriction", 0);

// Disallow JavaScript to move and resize windows.
user_pref("dom.disable_window_move_resize", true);

// -----------------------------------------------------------------------------
// Network
// -----------------------------------------------------------------------------

// Disable prefetching.
user_pref("network.prefetch-next", false);
user_pref("network.predictor.enabled", false);
user_pref("network.predictor.enable-prefetch", false);
user_pref("network.dns.disablePrefetch", true);
user_pref("network.dns.disablePrefetchFromHTTPS", true);

// Disable making speculative connections when mouseover.
user_pref("network.http.speculative-parallel-limit", 0);

// Disable sending additional analytics to web servers.
user_pref("beacon.enabled", false);

// Disable sending full referer header across origins.
user_pref("network.http.referer.XOriginPolicy", 1);
user_pref("network.http.referer.XOriginTrimmingPolicy", 2);

// Disable HTTP authentication credentials dialogs triggered by cross-origin
// sub-resources.
user_pref("network.auth.subresource-http-auth-allow", 1);

// Disable Captive Portal detection.
user_pref("network.captive-portal-service.enabled", false);
user_pref("captivedetect.canonicalURL", "");

// Disable Network Connectivity checks.
user_pref("network.connectivity-service.enabled", false);

// Disable automatic Work Offline mode.
user_pref("network.manage-offline-status", false);

// Enable proxying DNS when using SOCKS v5.
user_pref("network.proxy.socks_remote_dns", true);

// -----------------------------------------------------------------------------
// Privacy
// -----------------------------------------------------------------------------

// Block all third-party cookies.
user_pref("network.cookie.cookieBehavior", 1);
user_pref("browser.contentblocking.category", "custom");

// Enable FPI (First Party Isolation).
user_pref("privacy.firstparty.isolate", true);

// Enable Enhanced Tracking Protection.
user_pref("privacy.trackingprotection.enabled", true);
user_pref("privacy.trackingprotection.pbmode.enabled", true);
user_pref("privacy.trackingprotection.cryptomining.enabled", true);
user_pref("privacy.trackingprotection.fingerprinting.enabled", true);
user_pref("privacy.trackingprotection.socialtracking.enabled", true);

// Enable DNT (Do Not Track) HTTP header.
user_pref("privacy.donottrackheader.enabled", true);

// Disable Telemetry.
user_pref("toolkit.telemetry.unified", false);
user_pref("toolkit.telemetry.enabled", false);
user_pref("toolkit.telemetry.server", "data:,");
user_pref("toolkit.telemetry.archive.enabled", false);
user_pref("toolkit.telemetry.bhrPing.enabled", false);
user_pref("toolkit.telemetry.firstShutdownPing.enabled", false);
user_pref("toolkit.telemetry.newProfilePing.enabled", false);
user_pref("toolkit.telemetry.shutdownPingSender.enabled", false);
user_pref("toolkit.telemetry.updatePing.enabled", false);

// Disable Telemetry Coverage.
user_pref("toolkit.telemetry.coverage.opt-out", true);
user_pref("toolkit.coverage.opt-out", true);
user_pref("toolkit.coverage.endpoint.base", "");

// Disable Health Report.
user_pref("datareporting.healthreport.uploadEnabled", false);
user_pref("datareporting.policy.dataSubmissionEnabled", false);

// Disable Shield Studies.
user_pref("app.shield.optoutstudies.enabled", false);

// Disable Normandy Telemetry.
user_pref("app.normandy.enabled", false);
user_pref("app.normandy.api_url", "");

// Disable sending file information to Google Safe Browsing service.
user_pref("browser.safebrowsing.downloads.remote.enabled", false);
user_pref("browser.safebrowsing.downloads.remote.url", "");

// Disable sending browser crash reports.
user_pref("breakpad.reportURL", "");
user_pref("browser.tabs.crashReporting.sendReport", false);
user_pref("browser.crashReports.unsubmittedCheck.enabled", false);
user_pref("browser.crashReports.unsubmittedCheck.autoSubmit2", false);

// Disable sending plugin crash reports.
user_pref("dom.ipc.plugins.flash.subprocess.crashreporter.enabled", false);
user_pref("dom.ipc.plugins.reportCrashURL", false);

// -----------------------------------------------------------------------------
// Security
// -----------------------------------------------------------------------------

// Disable saving logins and passwords.
user_pref("signon.rememberSignons", false);

// Enforce OCSP (Online Certificate Status Protocol) stapling.
user_pref("security.ssl.enable_ocsp_stapling", true);
user_pref("security.OCSP.enabled", 1);
user_pref("security.OCSP.require", true);

// Enforce CSP (Content Security Policy).
user_pref("security.csp.enable", true);

// Enforce no insecure content on HTTPS pages.
user_pref("security.mixed_content.block_active_content", true);
user_pref("security.mixed_content.block_display_content", true);
user_pref("security.mixed_content.block_object_subrequest", true);

// -----------------------------------------------------------------------------
// Search
// -----------------------------------------------------------------------------

// Disable search engine updates.
user_pref("browser.search.update", false);

// Enable search suggestions in all windows.
user_pref("browser.search.suggest.enabled", true);
user_pref("browser.search.suggest.enabled.private", true);
user_pref("browser.urlbar.suggest.searches", true);

// Show search suggestions behind other suggestions.
user_pref("browser.urlbar.showSearchSuggestionsFirst", false);

// -----------------------------------------------------------------------------
// Features
// -----------------------------------------------------------------------------

// Disable Firefox Accounts and Sync.
user_pref("identity.fxaccounts.enabled", false);

// Disable Reader View.
user_pref("reader.parse-on-load.enabled", false);

// Disable UITour backend.
user_pref("browser.uitour.enabled", false);
user_pref("browser.uitour.url", "");

// Disable various developer tools.
user_pref("devtools.chrome.enabled", false);
user_pref("devtools.debugger.remote-enabled", false);

// -----------------------------------------------------------------------------
// Add-ons
// -----------------------------------------------------------------------------

// Enable all extensions in Private Windows by default.
user_pref("extensions.allowPrivateBrowsingByDefault", true);

// Disable enforced extension signing in Developer Edition, Nightly and ESR.
user_pref("xpinstall.signatures.required", false);

// Disable extension recommendations in about:addons.
user_pref("extensions.getAddons.showPane", false);
user_pref("extensions.htmlaboutaddons.recommendations.enabled", false);

// Disable extension recommendations when browsing.
user_pref("browser.newtabpage.activity-stream.asrouter.userprefs.cfr.addons", false);
user_pref("browser.newtabpage.activity-stream.asrouter.userprefs.cfr.features", false);

// Disable third-party extension install prompts.
user_pref("extensions.postDownloadThirdPartyPrompt", false);

// Disable system add-on updates.
user_pref("extensions.systemAddon.update.enabled", false);
user_pref("extensions.systemAddon.update.url", "");

// Disable Form Autofill.
user_pref("extensions.formautofill.available", "off");
user_pref("extensions.formautofill.addresses.enabled", false);
user_pref("extensions.formautofill.creditCards.available", false);
user_pref("extensions.formautofill.creditCards.enabled", false);
user_pref("extensions.formautofill.heuristics.enabled", false);

// Disable Pocket.
user_pref("extensions.pocket.enabled", false);

// Disable Web Compatibility Reporter.
user_pref("extensions.webcompat-reporter.enabled", false);

// Disable Gecko Media Plugins.
user_pref("media.gmp-provider.enabled", false);
user_pref("media.gmp-gmpopenh264.enabled", false);
user_pref("media.gmp-widevinecdm.enabled", false);

// Disable DRM-controlled content.
user_pref("media.eme.enabled", false);

// -----------------------------------------------------------------------------
// System
// -----------------------------------------------------------------------------

// Disable automatic Firefox updates.
user_pref("app.update.auto", false);

// Disable accessibility services.
user_pref("accessibility.force_disabled", 1);

// Disable disk cache.
user_pref("browser.cache.disk.enable", false);
user_pref("browser.cache.offline.storage.enable", false);
user_pref("browser.privatebrowsing.forceMediaMemoryCache", true);
user_pref("media.memory_cache_max_size", 65536);

// Disable saving page thumbnails.
user_pref("browser.pagethumbnails.capturing_disabled", true);

// Disable saving shortcut favicons.
user_pref("browser.shell.shortcutFavicons", false);

// Set the maximum number of bookmark backups to keep.
user_pref("browser.bookmarks.max_backups", 5);

// Set the minimum interval between session save operations.
user_pref("browser.sessionstore.interval", 60000);

// Always ask where to save files.
user_pref("browser.download.useDownloadDir", false);

// Disable adding downloads to Recent Documents.
user_pref("browser.download.manager.addToRecentDocs", false);

// Disable automatic start and session restore after Windows reboot.
user_pref("toolkit.winRegisterApplicationRestart", false);

// -----------------------------------------------------------------------------
// Appearance
// -----------------------------------------------------------------------------

// Enable userChrome.css and userContent.css customizations.
user_pref("toolkit.legacyUserProfileCustomizations.stylesheets", true);

// Disable site-specific zoom level.
user_pref("browser.zoom.siteSpecific", false);

// Show the full URL in address bar.
user_pref("browser.urlbar.trimURLs", false);

// Show the Punycode for IDNs (Internationalized Domain Names) in address bar.
user_pref("network.IDN_show_punycode", true);

// Show "Downloads" button in toolbar.
user_pref("browser.download.autohideButton", false);

// Hide "What's New" button in toolbar.
user_pref("browser.messaging-system.whatsNewPanel.enabled", false);

// Show weak encryption warning in address bar.
user_pref("security.ssl.require_safe_negotiation", false);
user_pref("security.ssl.treat_unsafe_negotiation_as_broken", true);

// Show advanced information in insecure connection warning pages.
user_pref("browser.xul.error_pages.expert_bad_cert", true);

// -----------------------------------------------------------------------------
// Miscellaneous
// -----------------------------------------------------------------------------

// Disable about:config warning.
user_pref("general.warnOnAboutConfig", false);
user_pref("browser.aboutConfig.showWarning", false);

// Disable form and search history.
user_pref("browser.formfill.enable", false);

// Disable address bar guessing domain.
user_pref("browser.fixup.alternate.enabled", false);

// Disable address bar encoding Unicode characters when copying the URL.
user_pref("browser.urlbar.decodeURLsOnCopy", true);

// Disable address bar making speculative connections.
user_pref("browser.urlbar.speculativeConnect.enabled", false);

// Disable address bar sending search term to DNS server.
user_pref("browser.urlbar.dnsResolveSingleWordsAfterSearch", 0);

// Set the suggestion types in address bar.
user_pref("browser.urlbar.suggest.history", false);
user_pref("browser.urlbar.suggest.bookmark", true);
user_pref("browser.urlbar.suggest.openpage", true);
user_pref("browser.urlbar.suggest.topsites", false);
user_pref("browser.urlbar.suggest.engines", false);

// Set the security delay on some confirmation dialogs.
user_pref("security.dialog_enable_delay", 500);

// Disable closing window with last tab.
user_pref("browser.tabs.closeWindowWithLastTab", false);

// Disable Backspace key navigation.
user_pref("browser.backspace_action", 2);

// Disable Ctrl+Q as quit shortcut.
user_pref("browser.quitShortcut.disabled", true);

// Disable Alt as menu access key.
user_pref("ui.key.menuAccessKey", 0);

// Disable selecting any extra spaces when double-clicking text.
user_pref("layout.word_select.eat_space_to_next_word", false);

// -----------------------------------------------------------------------------
// ESR
// -----------------------------------------------------------------------------

// ESR 78.* still uses the following preferences.
user_pref("browser.search.geoSpecificDefaults", false);
user_pref("browser.search.geoSpecificDefaults.url", "");
user_pref("browser.library.activity-stream.enabled", false);
user_pref("browser.urlbar.matchBuckets", "general:5,suggestion:Infinity");
<commit_msg>firefox: Update user.js to 89.0<commit_after>// Firefox user.js

// -----------------------------------------------------------------------------
// Startup
// -----------------------------------------------------------------------------

// Show a blank page when opening homepage and new window.
user_pref("browser.startup.page", 0);
user_pref("browser.startup.homepage", "about:blank");
user_pref("browser.startup.homepage_override.mstone", "ignore");

// Show a blank page when opening new tab.
user_pref("browser.newtabpage.enabled", false);
user_pref("browser.newtab.preload", false);

// Disable Activity Stream.
user_pref("browser.newtabpage.activity-stream.default.sites", "");
user_pref("browser.newtabpage.activity-stream.feeds.discoverystreamfeed", false);
user_pref("browser.newtabpage.activity-stream.feeds.section.highlights", false);
user_pref("browser.newtabpage.activity-stream.feeds.section.topstories", false);
user_pref("browser.newtabpage.activity-stream.feeds.snippets", false);
user_pref("browser.newtabpage.activity-stream.feeds.telemetry", false);
user_pref("browser.newtabpage.activity-stream.feeds.topsites", false);
user_pref("browser.newtabpage.activity-stream.showSearch", false);
user_pref("browser.newtabpage.activity-stream.showSponsored", false);
user_pref("browser.newtabpage.activity-stream.telemetry", false);

// -----------------------------------------------------------------------------
// Localization
// -----------------------------------------------------------------------------

// Set preferred language for displaying pages.
user_pref("intl.accept_languages", "ja,zh-tw,zh,en-us,en");

// Disable region updates.
user_pref("browser.region.update.enabled", false);
user_pref("browser.region.network.url", "");

// -----------------------------------------------------------------------------
// Content
// -----------------------------------------------------------------------------

// Set the minimum font size.
user_pref("font.minimum-size.ja", 10);
user_pref("font.minimum-size.ko", 10);
user_pref("font.minimum-size.zh-CN", 10);
user_pref("font.minimum-size.zh-HK", 10);
user_pref("font.minimum-size.zh-TW", 10);

// Disable WebRTC.
user_pref("media.peerconnection.enabled", false);
user_pref("media.peerconnection.ice.default_address_only", true);
user_pref("media.peerconnection.ice.no_host", true);
user_pref("media.peerconnection.ice.proxy_only_if_behind_proxy", true);

// Disable media device enumeration.
user_pref("media.navigator.enabled", false);

// Block all audio and video autoplay.
user_pref("media.autoplay.default", 5);
user_pref("media.autoplay.blocking_policy", 0);

// Block new requests asking for permissions.
user_pref("permissions.default.geo", 2);
user_pref("permissions.default.camera", 2);
user_pref("permissions.default.microphone", 2);
user_pref("permissions.default.desktop-notification", 2);
user_pref("permissions.default.xr", 2);
user_pref("permissions.default.shortcuts", 2);

// Block pop-up windows.
user_pref("dom.disable_open_during_load", true);
user_pref("dom.popup_allowed_events", "click dblclick mousedown mouseup pointerdown pointerup");

// Enforce all links to be opened in new tabs.
user_pref("browser.link.open_newwindow", 3);
user_pref("browser.link.open_newwindow.restriction", 0);

// Disallow JavaScript to move and resize windows.
user_pref("dom.disable_window_move_resize", true);

// -----------------------------------------------------------------------------
// Network
// -----------------------------------------------------------------------------

// Disable prefetching.
user_pref("network.prefetch-next", false);
user_pref("network.predictor.enabled", false);
user_pref("network.predictor.enable-prefetch", false);
user_pref("network.dns.disablePrefetch", true);
user_pref("network.dns.disablePrefetchFromHTTPS", true);

// Disable making speculative connections when mouseover.
user_pref("network.http.speculative-parallel-limit", 0);

// Disable sending additional analytics to web servers.
user_pref("beacon.enabled", false);

// Disable sending full referer header across origins.
user_pref("network.http.referer.XOriginPolicy", 1);
user_pref("network.http.referer.XOriginTrimmingPolicy", 2);

// Disable HTTP authentication credentials dialogs triggered by cross-origin
// sub-resources.
user_pref("network.auth.subresource-http-auth-allow", 1);

// Disable Captive Portal detection.
user_pref("network.captive-portal-service.enabled", false);
user_pref("captivedetect.canonicalURL", "");

// Disable Network Connectivity checks.
user_pref("network.connectivity-service.enabled", false);

// Disable automatic Work Offline mode.
user_pref("network.manage-offline-status", false);

// Enable proxying DNS when using SOCKS v5.
user_pref("network.proxy.socks_remote_dns", true);

// -----------------------------------------------------------------------------
// Privacy
// -----------------------------------------------------------------------------

// Block all third-party cookies.
user_pref("network.cookie.cookieBehavior", 1);
user_pref("browser.contentblocking.category", "custom");

// Enable FPI (First Party Isolation).
user_pref("privacy.firstparty.isolate", true);

// Enable Enhanced Tracking Protection.
user_pref("privacy.trackingprotection.enabled", true);
user_pref("privacy.trackingprotection.pbmode.enabled", true);
user_pref("privacy.trackingprotection.cryptomining.enabled", true);
user_pref("privacy.trackingprotection.fingerprinting.enabled", true);
user_pref("privacy.trackingprotection.socialtracking.enabled", true);

// Enable DNT (Do Not Track) HTTP header.
user_pref("privacy.donottrackheader.enabled", true);

// Disable Telemetry.
user_pref("toolkit.telemetry.unified", false);
user_pref("toolkit.telemetry.enabled", false);
user_pref("toolkit.telemetry.server", "data:,");
user_pref("toolkit.telemetry.archive.enabled", false);
user_pref("toolkit.telemetry.bhrPing.enabled", false);
user_pref("toolkit.telemetry.firstShutdownPing.enabled", false);
user_pref("toolkit.telemetry.newProfilePing.enabled", false);
user_pref("toolkit.telemetry.shutdownPingSender.enabled", false);
user_pref("toolkit.telemetry.updatePing.enabled", false);

// Disable Telemetry Coverage.
user_pref("toolkit.telemetry.coverage.opt-out", true);
user_pref("toolkit.coverage.opt-out", true);
user_pref("toolkit.coverage.endpoint.base", "");

// Disable Health Report.
user_pref("datareporting.healthreport.uploadEnabled", false);
user_pref("datareporting.policy.dataSubmissionEnabled", false);

// Disable Shield Studies.
user_pref("app.shield.optoutstudies.enabled", false);

// Disable Normandy Telemetry.
user_pref("app.normandy.enabled", false);
user_pref("app.normandy.api_url", "");

// Disable sending file information to Google Safe Browsing service.
user_pref("browser.safebrowsing.downloads.remote.enabled", false);
user_pref("browser.safebrowsing.downloads.remote.url", "");

// Disable sending browser crash reports.
user_pref("breakpad.reportURL", "");
user_pref("browser.tabs.crashReporting.sendReport", false);
user_pref("browser.crashReports.unsubmittedCheck.enabled", false);
user_pref("browser.crashReports.unsubmittedCheck.autoSubmit2", false);

// -----------------------------------------------------------------------------
// Security
// -----------------------------------------------------------------------------

// Disable saving logins and passwords.
user_pref("signon.rememberSignons", false);

// Enforce OCSP (Online Certificate Status Protocol) stapling.
user_pref("security.ssl.enable_ocsp_stapling", true);
user_pref("security.OCSP.enabled", 1);
user_pref("security.OCSP.require", true);

// Enforce CSP (Content Security Policy).
user_pref("security.csp.enable", true);

// Enforce no insecure content on HTTPS pages.
user_pref("security.mixed_content.block_active_content", true);
user_pref("security.mixed_content.block_display_content", true);

// -----------------------------------------------------------------------------
// Search
// -----------------------------------------------------------------------------

// Disable search engine updates.
user_pref("browser.search.update", false);

// Enable search suggestions in all windows.
user_pref("browser.search.suggest.enabled", true);
user_pref("browser.search.suggest.enabled.private", true);
user_pref("browser.urlbar.suggest.searches", true);

// Show search suggestions behind other suggestions.
user_pref("browser.urlbar.showSearchSuggestionsFirst", false);

// -----------------------------------------------------------------------------
// Features
// -----------------------------------------------------------------------------

// Disable Firefox Accounts and Sync.
user_pref("identity.fxaccounts.enabled", false);

// Disable Reader View.
user_pref("reader.parse-on-load.enabled", false);

// Disable UITour backend.
user_pref("browser.uitour.enabled", false);
user_pref("browser.uitour.url", "");

// Disable various developer tools.
user_pref("devtools.chrome.enabled", false);
user_pref("devtools.debugger.remote-enabled", false);

// -----------------------------------------------------------------------------
// Add-ons
// -----------------------------------------------------------------------------

// Enable all extensions in Private Windows by default.
user_pref("extensions.allowPrivateBrowsingByDefault", true);

// Disable enforced extension signing in Developer Edition, Nightly and ESR.
user_pref("xpinstall.signatures.required", false);

// Disable extension recommendations in about:addons.
user_pref("extensions.getAddons.showPane", false);
user_pref("extensions.htmlaboutaddons.recommendations.enabled", false);

// Disable extension recommendations when browsing.
user_pref("browser.newtabpage.activity-stream.asrouter.userprefs.cfr.addons", false);
user_pref("browser.newtabpage.activity-stream.asrouter.userprefs.cfr.features", false);

// Disable third-party extension install prompts.
user_pref("extensions.postDownloadThirdPartyPrompt", false);

// Disable system add-on updates.
user_pref("extensions.systemAddon.update.enabled", false);
user_pref("extensions.systemAddon.update.url", "");

// Disable Form Autofill.
user_pref("extensions.formautofill.available", "off");
user_pref("extensions.formautofill.addresses.enabled", false);
user_pref("extensions.formautofill.creditCards.available", false);
user_pref("extensions.formautofill.creditCards.enabled", false);
user_pref("extensions.formautofill.heuristics.enabled", false);

// Disable Pocket.
user_pref("extensions.pocket.enabled", false);

// Disable Web Compatibility Reporter.
user_pref("extensions.webcompat-reporter.enabled", false);

// Disable Gecko Media Plugins.
user_pref("media.gmp-provider.enabled", false);
user_pref("media.gmp-gmpopenh264.enabled", false);
user_pref("media.gmp-widevinecdm.enabled", false);

// Disable DRM-controlled content.
user_pref("media.eme.enabled", false);

// -----------------------------------------------------------------------------
// System
// -----------------------------------------------------------------------------

// Disable automatic Firefox updates.
user_pref("app.update.auto", false);

// Disable accessibility services.
user_pref("accessibility.force_disabled", 1);

// Disable disk cache.
user_pref("browser.cache.disk.enable", false);
user_pref("browser.cache.offline.storage.enable", false);
user_pref("browser.privatebrowsing.forceMediaMemoryCache", true);
user_pref("media.memory_cache_max_size", 65536);

// Disable saving page thumbnails.
user_pref("browser.pagethumbnails.capturing_disabled", true);

// Disable saving shortcut favicons.
user_pref("browser.shell.shortcutFavicons", false);

// Set the maximum number of bookmark backups to keep.
user_pref("browser.bookmarks.max_backups", 5);

// Set the minimum interval between session save operations.
user_pref("browser.sessionstore.interval", 60000);

// Always ask where to save files.
user_pref("browser.download.useDownloadDir", false);

// Disable adding downloads to Recent Documents.
user_pref("browser.download.manager.addToRecentDocs", false);

// Disable automatic start and session restore after Windows reboot.
user_pref("toolkit.winRegisterApplicationRestart", false);

// -----------------------------------------------------------------------------
// Appearance
// -----------------------------------------------------------------------------

// Enable userChrome.css and userContent.css customizations.
user_pref("toolkit.legacyUserProfileCustomizations.stylesheets", true);

// Disable site-specific zoom level.
user_pref("browser.zoom.siteSpecific", false);

// Show the full URL in address bar.
user_pref("browser.urlbar.trimURLs", false);

// Show the Punycode for IDNs (Internationalized Domain Names) in address bar.
user_pref("network.IDN_show_punycode", true);

// Show "Downloads" button in toolbar.
user_pref("browser.download.autohideButton", false);

// Hide "What's New" button in toolbar.
user_pref("browser.messaging-system.whatsNewPanel.enabled", false);

// Show weak encryption warning in address bar.
user_pref("security.ssl.require_safe_negotiation", false);
user_pref("security.ssl.treat_unsafe_negotiation_as_broken", true);

// Show advanced information in insecure connection warning pages.
user_pref("browser.xul.error_pages.expert_bad_cert", true);

// -----------------------------------------------------------------------------
// Miscellaneous
// -----------------------------------------------------------------------------

// Disable about:config warning.
user_pref("general.warnOnAboutConfig", false);
user_pref("browser.aboutConfig.showWarning", false);

// Disable form and search history.
user_pref("browser.formfill.enable", false);

// Disable address bar guessing domain.
user_pref("browser.fixup.alternate.enabled", false);

// Disable address bar encoding Unicode characters when copying the URL.
user_pref("browser.urlbar.decodeURLsOnCopy", true);

// Disable address bar making speculative connections.
user_pref("browser.urlbar.speculativeConnect.enabled", false);

// Disable address bar sending search term to DNS server.
user_pref("browser.urlbar.dnsResolveSingleWordsAfterSearch", 0);

// Set the suggestion types in address bar.
user_pref("browser.urlbar.suggest.history", false);
user_pref("browser.urlbar.suggest.bookmark", true);
user_pref("browser.urlbar.suggest.openpage", true);
user_pref("browser.urlbar.suggest.topsites", false);
user_pref("browser.urlbar.suggest.engines", false);

// Set the security delay on some confirmation dialogs.
user_pref("security.dialog_enable_delay", 500);

// Disable closing window with last tab.
user_pref("browser.tabs.closeWindowWithLastTab", false);

// Disable Backspace key navigation.
user_pref("browser.backspace_action", 2);

// Disable Ctrl+Q as quit shortcut.
user_pref("browser.quitShortcut.disabled", true);

// Disable Alt as menu access key.
user_pref("ui.key.menuAccessKey", 0);

// Disable selecting any extra spaces when double-clicking text.
user_pref("layout.word_select.eat_space_to_next_word", false);

// -----------------------------------------------------------------------------
// ESR
// -----------------------------------------------------------------------------

// ESR 78.* still uses the following preferences.
user_pref("browser.search.geoSpecificDefaults", false);
user_pref("browser.search.geoSpecificDefaults.url", "");
user_pref("browser.library.activity-stream.enabled", false);
user_pref("browser.urlbar.matchBuckets", "general:5,suggestion:Infinity");
user_pref("dom.ipc.plugins.flash.subprocess.crashreporter.enabled", false);
user_pref("dom.ipc.plugins.reportCrashURL", false);
user_pref("security.mixed_content.block_object_subrequest", true);
<|endoftext|>


<commit_before>import { authorizedFetch } from '../util/auth'

import AppSettings from '../AppSettings'
import logger from '../util/logger'

const ScheduleService = {
	* FetchSchedule(term, isStudentDemo) {
		const data = [],
			UN_API_URL = AppSettings.ACADEMIC_HISTORY_API_URL + '?academic_level=UN&term_code=' + term,
			GR_API_URL = AppSettings.ACADEMIC_HISTORY_API_URL + '?academic_level=GR&term_code=' + term

		// Query api for undergrad classes
		try {
			const undergrad = JSON.parse(yield authorizedFetch(UN_API_URL))
			if (undergrad.data && Array.isArray(undergrad.data)) {
				data.push(...undergrad.data)
			}
		} catch (err) {
			logger.trackException(err, false)
		}

		// Query api for graduate classes
		try {
			const grad = JSON.parse(yield authorizedFetch(GR_API_URL))
			if (grad.data && Array.isArray(grad.data)) {
				data.push(...grad.data)
			}
		} catch (err) {
			logger.trackException(err, false)
		}

		return { data }
	},

	FetchTerm(isStudentDemo) {
		return fetch(AppSettings.ACADEMIC_TERM_API_URL)
			.then(response => response.json())
			.then(responseData => responseData)
			.catch((error) => { throw error })
	},

	FetchFinals(isStudentDemo) {
		return fetch(AppSettings.ACADEMIC_TERM_FINALS_API_URL(isStudentDemo))
			.then(response => response.json())
			.then(responseData => responseData)
			.catch((error) => { throw error })
	}
}

export default ScheduleService
<commit_msg>Address an issue with the Finals card<commit_after>import { authorizedFetch } from '../util/auth'

import AppSettings from '../AppSettings'
import logger from '../util/logger'

const ScheduleService = {
	* FetchSchedule(term, isStudentDemo) {
		const data = [],
			UN_API_URL = AppSettings.ACADEMIC_HISTORY_API_URL + '?academic_level=UN&term_code=' + term,
			GR_API_URL = AppSettings.ACADEMIC_HISTORY_API_URL + '?academic_level=GR&term_code=' + term

		// Query api for undergrad classes
		try {
			const undergrad = JSON.parse(yield authorizedFetch(UN_API_URL))
			if (undergrad.data && Array.isArray(undergrad.data)) {
				data.push(...undergrad.data)
			}
		} catch (err) {
			logger.trackException(err, false)
		}

		// Query api for graduate classes
		try {
			const grad = JSON.parse(yield authorizedFetch(GR_API_URL))
			if (grad.data && Array.isArray(grad.data)) {
				data.push(...grad.data)
			}
		} catch (err) {
			logger.trackException(err, false)
		}

		return { data }
	},

	FetchTerm(isStudentDemo) {
		return fetch(AppSettings.ACADEMIC_TERM_API_URL)
			.then(response => response.json())
			.then(responseData => responseData)
			.catch((error) => { throw error })
	},

	FetchFinals(isStudentDemo) {
		return fetch(AppSettings.ACADEMIC_TERM_FINALS_API_URL)
			.then(response => response.json())
			.then(responseData => responseData)
			.catch((error) => { throw error })
	}
}

export default ScheduleService
<|endoftext|>


<commit_before>openerp.base = function(instance) {

// FIXME do not work on safari
// TODO test on IE
// FIXME when apps server is not available, redirect to failback action but do not highligth the good menu

    instance.base = {apps:{}};

    instance.base.apps.remote_instance = null;

    instance.base.apps.get_client = function() {
        // return the client via a deferred, resolved or rejected depending if the remote host is available or not.
        var check_client_available = function(client) {
            var d = $.Deferred();
            var i = new Image();
            i.onerror = function() {
                d.reject(client);
            };
            i.onload = function() {
                console.log('client is available', client);

                client.session.session_bind(client.origin).done(function() {
                    // check if client can authenticate
                    client.authenticate().done(function() {
                        d.resolve(client);
                    }).fail(function() {
                        if (client.login === 'anonymous') {
                            d.reject(client);
                        } else {
                            sessionStorage.removeItem('apps.login');
                            sessionStorage.removeItem('apps.access_token');
                            client.bind(client.dbname, 'anonymous', 'anonymous');
                            client.authenticate().done(function() {
                                d.resolve(client);
                            }).fail(function() {
                                d.reject(client);
                            });
                        }
                    });
                });

            };
            i.src = _.str.sprintf('%s/web/static/src/img/sep-a.gif', client.origin);
            return d.promise();
        };
        if (instance.base.apps._client) {
            return check_client_available(instance.base.apps._client);
        } else {
            //var DEFAULT_SERVER = 'http://apps.openerp.com/loempia';           // PROD
            var DEFAULT_SERVER = 'http://apps.v7.openerp.com:8069/apps';     // TEST
            //var DEFAULT_SERVER = 'http://localhost:8080/trunk_loempia7';        // DEV
            var ICP = new instance.web.Model('ir.config_parameter');
            return ICP.call('get_param', ['loempia.server', DEFAULT_SERVER]).then(function(u) {
                var link = $(_.str.sprintf('', u))[0];
                var host = _.str.sprintf('%s//%s', link.protocol, link.host);
                var dbname = link.pathname.substr(1);

                var login = (sessionStorage ? sessionStorage.getItem('apps.login') : null) || 'anonymous';
                var passwd = (sessionStorage ? sessionStorage.getItem('apps.access_token') : null) || 'anonymous';

                if (_.isNull(instance.base.apps.remote_instance)) {
                    instance.base.apps.remote_instance = new openerp.init();
                }
                var client = new instance.base.apps.remote_instance.web.EmbeddedClient(null, host,
                                                                         dbname, login, passwd);

                console.log('new client', client);
                instance.base.apps._client = client;
                return check_client_available(client);
            });
        }

    };

    instance.base.apps.Apps = instance.web.Widget.extend({
        template: 'EmptyComponent',

        remote_action_id: 'loempia.action_embed',
        failback_action_id: 'base.open_module_tree',

        init: function(parent, action) {
            this._super(parent, action);
            var options = action.params || {};

            if (options.apps_user) {
                sessionStorage.setItem('apps.login', options.apps_user);
            }
            if (options.apps_access_token) {
                sessionStorage.setItem('apps.access_token', options.apps_access_token);
            }

            this.params = options;      // NOTE read by embedded client action
        },

        clean: function() {
            instance.base.apps.get_client().always(function(client) { client.destroy(); });
        },

        destroy: function() {
            this.clean();
            return this._super();
        },

        start: function() {
            var self = this;
            console.time('apps');
            console.time('client');
            console.log('Apps.start()');
            return instance.base.apps.get_client().
                done(function(client) {
                    console.timeEnd('client');
                    client.replace(self.$el).
                        done(function() {
                            client.$el.removeClass('openerp');
                            console.timeEnd('apps');
                            client.do_action(self.remote_action_id);
                        });
                }).
                fail(function(client) {
                    self.do_warn('Apps Server not reachable.', 'Showing local modules.', true);
                    self.do_action(self.failback_action_id);
                });
        },

        0:0
    });

    instance.base.apps.UpdatesAvailable = instance.base.apps.Apps.extend({
        remote_action_id: 'loempia.action_embed_updates'
    });

    instance.web.client_actions.add("apps", "instance.base.apps.Apps");
    instance.web.client_actions.add("apps.updates", "instance.base.apps.UpdatesAvailable");

};
<commit_msg>[FIX] correct then/done errors + highlight "installed modules" menu when apps is not reachable<commit_after>openerp.base = function(instance) {

// FIXME do not work on safari
// TODO test on IE
// FIXME when apps server is not available, redirect to failback action but do not highligth the good menu

    instance.base = {apps:{}};

    instance.base.apps.remote_instance = null;

    instance.base.apps.get_client = function() {
        // return the client via a deferred, resolved or rejected depending if the remote host is available or not.
        var check_client_available = function(client) {
            var d = $.Deferred();
            var i = new Image();
            i.onerror = function() {
                d.reject(client);
            };
            i.onload = function() {
                console.log('client is available', client);

                client.session.session_bind(client.origin).then(function() {
                    // check if client can authenticate
                    client.authenticate().then(
                       function() {     /* done */
                        d.resolve(client);
                    }, function() {     /* fail */
                        if (client.login === 'anonymous') {
                            d.reject(client);
                        } else {
                            sessionStorage.removeItem('apps.login');
                            sessionStorage.removeItem('apps.access_token');
                            client.bind(client.dbname, 'anonymous', 'anonymous');
                            client.authenticate().then(
                               function() {     /* done */
                                d.resolve(client);
                            }, function() {     /* fail */
                                d.reject(client);
                            });
                        }
                    });
                });

            };
            i.src = _.str.sprintf('%s/web/static/src/img/sep-a.gif', client.origin);
            return d.promise();
        };
        if (instance.base.apps._client) {
            return check_client_available(instance.base.apps._client);
        } else {
            //var DEFAULT_SERVER = 'http://apps.openerp.com/loempia';           // PROD
            var DEFAULT_SERVER = 'http://apps.v7.openerp.com:8069/apps';     // TEST
            //var DEFAULT_SERVER = 'http://localhost:8080/trunk_loempia7';        // DEV
            var ICP = new instance.web.Model('ir.config_parameter');
            return ICP.call('get_param', ['loempia.server', DEFAULT_SERVER]).then(function(u) {
                var link = $(_.str.sprintf('', u))[0];
                var host = _.str.sprintf('%s//%s', link.protocol, link.host);
                var dbname = link.pathname.substr(1);

                var login = (sessionStorage ? sessionStorage.getItem('apps.login') : null) || 'anonymous';
                var passwd = (sessionStorage ? sessionStorage.getItem('apps.access_token') : null) || 'anonymous';

                if (_.isNull(instance.base.apps.remote_instance)) {
                    instance.base.apps.remote_instance = new openerp.init();
                }
                var client = new instance.base.apps.remote_instance.web.EmbeddedClient(null, host,
                                                                         dbname, login, passwd);

                console.log('new client', client);
                instance.base.apps._client = client;
                return check_client_available(client);
            });
        }

    };

    instance.base.apps.Apps = instance.web.Widget.extend({
        template: 'EmptyComponent',

        remote_action_id: 'loempia.action_embed',
        failback_action_id: 'base.open_module_tree',

        init: function(parent, action) {
            this._super(parent, action);
            var options = action.params || {};

            if (options.apps_user) {
                sessionStorage.setItem('apps.login', options.apps_user);
            }
            if (options.apps_access_token) {
                sessionStorage.setItem('apps.access_token', options.apps_access_token);
            }

            this.params = options;      // NOTE read by embedded client action
        },

        clean: function() {
            instance.base.apps.get_client().always(function(client) { client.destroy(); });
        },

        destroy: function() {
            this.clean();
            return this._super();
        },

        start: function() {
            var self = this;
            console.time('apps');
            console.time('client');
            console.log('Apps.start()');
            return instance.base.apps.get_client().
                done(function(client) {
                    console.timeEnd('client');
                    client.replace(self.$el).
                        done(function() {
                            client.$el.removeClass('openerp');
                            console.timeEnd('apps');
                            client.do_action(self.remote_action_id);
                        });
                }).
                fail(function(client) {
                    self.do_warn('Apps Server not reachable.', 'Showing local modules.', true);
                    self.rpc('/web/action/load', {action_id: self.failback_action_id}).done(function(action) {
                        self.do_action(action);
                        instance.webclient.menu.open_action(action.id);
                    });
                });
        },

        0:0
    });

    instance.base.apps.UpdatesAvailable = instance.base.apps.Apps.extend({
        remote_action_id: 'loempia.action_embed_updates'
    });

    instance.web.client_actions.add("apps", "instance.base.apps.Apps");
    instance.web.client_actions.add("apps.updates", "instance.base.apps.UpdatesAvailable");

};
<|endoftext|>


<commit_before>document.getElementById("id_business_level_version").innerHTML = "Business level version: 2018.01.11.0";

navigator.geolocation.watchPosition(on_gps_success, on_gps_error);

var marker;
//--------------------------------------
function on_gps_success(p)
{
	document.getElementById("id_p").innerHTML = "lat = " +
	p.coords.latitude + "
long = " + p.coords.longitude +
	"
accuracy = " + p.coords.accuracy + "m" +
	"
altitude = " + p.coords.altitude + "m"+
	"
speed = " + p.coords.speed + "m/s";

	var map_obj = new google.maps.Map(document.getElementById("id_map"));
	map_obj.setCenter({lat:p.coords.latitude, lng:p.coords.longitude});
	map_obj.setZoom(10);

	marker = new google.maps.Marker({
    position: {lat:p.coords.latitude, lng:p.coords.longitude},
    title:"LMM!",
	map:map_obj,
	animation: google.maps.Animation.DROP
	});
	marker.addListener("click", on_marker_click);
}
//--------------------------------------
function on_marker_click()
{
	if (marker.getAnimation() !== null) {
		marker.setAnimation(null);
	} else {
		marker.setAnimation(google.maps.Animation.BOUNCE);
	}
}
//--------------------------------------
function on_gps_error(e)
{
	alert(e.code);
}
//--------------------------------------<commit_msg>proiect<commit_after>document.getElementById("id_business_level_version").innerHTML = "Business level version: 2017.12.10.0";

navigator.geolocation.watchPosition(on_gps_success, on_gps_error);

var marker;
//--------------------------------------
function on_gps_success(p)
{
	document.getElementById("id_p").innerHTML = "lat = " +
	p.coords.latitude + "
long = " + p.coords.longitude +
	"
accuracy = " + p.coords.accuracy + "m" +
	"
altitude = " + p.coords.altitude + "m"+
	"
speed = " + p.coords.speed + "m/s";

	var map_obj = new google.maps.Map(document.getElementById("id_map"));
	map_obj.setCenter({lat:p.coords.latitude, lng:p.coords.longitude});
	map_obj.setZoom(10);

	marker = new google.maps.Marker({
    position: {lat:p.coords.latitude, lng:p.coords.longitude},
    title:"LMM!",
	map:map_obj,
	animation: google.maps.Animation.DROP
	});
	marker.addListener("click", on_marker_click);
}
//--------------------------------------
function on_marker_click()
{
	if (marker.getAnimation() !== null) {
		marker.setAnimation(null);
	} else {
		marker.setAnimation(google.maps.Animation.BOUNCE);
	}
}
//--------------------------------------
function on_gps_error(e)
{
	alert(e.code);
}
//--------------------------------------<|endoftext|>


<commit_before>describe("A URL", function() {
	describe("with http", function() {
		it("should be able to extract the domain", function() {
			expect(getDomain('http://www.google.com')).toMatch('www.google.com');
			expect(getDomain('http://www.google.com/')).toMatch('www.google.com');
			expect(getDomain('http://www.google.com/kitty')).toMatch('www.google.com');
		});

		it("should be able to extract the hostname", function() {
			expect(getDomain('http://www.google.com')).toMatch('google.com');
			expect(getDomain('http://www.google.com/')).toMatch('google.com');
			expect(getDomain('http://www.google.com/kitty')).toMatch('google.com');
		});
	});

	describe("with https", function() {
		it("should be able to extract the domain", function() {
			expect(getDomain('https://www.google.com')).toMatch('www.google.com');
			expect(getDomain('https://www.google.com/')).toMatch('www.google.com');
			expect(getDomain('https://www.google.com/kitty')).toMatch('www.google.com');
		});
		it("should be able to extract the hostname", function() {
			expect(getDomain('https://www.google.com')).toMatch('google.com');
			expect(getDomain('https://www.google.com/')).toMatch('google.com');
			expect(getDomain('https://www.google.com/kitty')).toMatch('google.com');
		});
	});

	describe("that is a chrome URL", function() {
		it("should be detected with no subdirectories", function() {
			expect(isChromeURL("chrome://newtabpage"));
		});

		it("should be detected with subdirectories", function() {
			expect(isChromeURL("chrome://newtabpage/kitty/meow"));
			expect(isChromeURL("chrome://newtabpage/kitty/meow/"));
		});
	});

	describe("that is an extension URL", function() {
		var url = chrome.extension.getURL("/");

		it("should be detected with no subdirectories", function() {
			expect(isExtensionURL(url));
		});

		it("should be detected with subdirectories", function() {
			expect(isExtensionURL(url + "test"));
			expect(isExtensionURL(url + "test/"));
		});

		it("should be detected if it is the new tab page", function() {
			expect(isExtensionURL("chrome://newtab"));
			expect(isExtensionURL("chrome://newtab/"));
		})
	});
});

describe("A loop", function() {
	var answer;

	beforeEach(function(done) {
		answer = null;
		done();
	});

	it("should repeat the right number of times", function() {
		runs(function(done) {
			answer = 0;

			loop(0, 5, function(i, next) {
				answer += i;

				next();
			}, done);
		});

		runs(function(done) {
			expect(answer).toBe(10);
			done();
		});
	});

	it("should not run when the end is less than the iteration", function() {
		runs(function(done) {
			answer = 0;

			loop(5, -1, function(i, next) {
				answer += i;

				next();
			}, done);
		});

		runs(function(done) {
			expect(answer).toBe(0);
			done();
		});
	});
});

describe("An asynchronous loop", function() {
	var answer;

	beforeEach(function(done) {
		answer = null;
		done();
	});

	describe("when the end is greater than the start", function() {
		it("should repeat the right number of times", function() {
			runs(function(done) {
				answer = 0;

				async_loop(0, 5, function(iteration, callback) {
					answer += iteration;

					callback();
				}, done);
			});

			runs(function(done) {
				expect(answer).toBe(10);
				done();
			});
		});
	});

	describe("when the end is one more than the start", function() {
		it("should repeat the right number of times", function() {
			runs(function(done) {
				answer = 1;

				async_loop(0, 1, function(iteration, callback) {
					answer += iteration;

					callback();
				}, done);
			});

			runs(function(done) {
				expect(answer).toBe(1);
				done();
			});
		});
	});

	describe("when the end is less than the start", function() {
		it("should not run", function() {
			runs(function(done) {
				answer = 0;

				async_loop(5, -1, function(iteration, callback) {
					answer += iteration;

					callback();
				}, done);
			});

			runs(function(done) {
				expect(answer).toBe(0);
				done();
			});
		});
	});

	describe("when running asynchronous operations", function() {
		it("should run them in any order", function() {
			runs(function(done) {
				answer = [];

				async_loop(0, 5, function(iteration, callback) {
					setTimeout(function() {
						answer.push(iteration);

						callback();
					}, 500 - iteration * 100);
				}, done);
			});

			runs(function(done) {
				expect(answer).toEqual([4, 3, 2, 1, 0]);
				done();
			});
		});

		it("should wait for the asynchronous operations to finish", function() {
			runs(function(done) {
				answer = [];

				async_loop(0, 5, function(iteration, callback) {
					setTimeout(function() {
						answer.push(iteration);

						callback();
					});
				}, done);
			});

			runs(function(done) {
				expect(answer).toEqual([0, 1, 2, 3, 4]);
				done();
			});
		});
	});
});

describe("An HTTP request", function() {
	var server = null;
	var success, error, response;

	beforeEach(function(done) {
		server = sinon.fakeServer.create();

		success = false;
		error = false;
		response = null;
		done();
	});

	afterEach(function(done) {
		server.restore();
		done();
	});

	describe("making a request that will respond 200", function() {
		beforeEach(function(done) {
			server.respondWith("GET", "/", [200, { "Content-Type": "text/html"}, "yay"]);

			makeHTTPRequest('/', function(res, headers) {
				response = res;

				success = true;
				done();
			}, function(status) {
				error = true;
				done();
			});

			server.respond();
		});

		it("should be successful", function() {
			expect(success).toBe(true);
			expect(error).toBe(false);
		});

		it("should have the correct response", function() {
			expect(response).toEqual("yay");
		});
	});

	describe("making a request that will respond 404", function() {
		beforeEach(function(done) {
			server.respondWith("GET", "/", [404, { "Content-Type": "text/html"}, "yay"]);

			makeHTTPRequest('/', function(res, headers) {
				response = res;

				success = true;
				done();
			}, function(status) {
				error = true;
				done();
			});

			server.respond();
		});

		it("should not be successful", function() {
			expect(success).toBe(false);
			expect(error).toBe(true);
		});

		it("should have no response", function() {
			expect(response).toBeNull();
		});
	});

	describe("making a request that will respond 301", function() {
		beforeEach(function(done) {
			server.respondWith("GET", "/", [301, { "Content-Type": "text/html"}, "yay"]);

			makeHTTPRequest('/', function(res, headers) {
				response = res;

				success = true;
				done();
			}, function(status) {
				error = true;
				done();
			});

			server.respond();
		});

		it("should not be successful", function() {
			expect(success).toBe(false);
			expect(error).toBe(true);
		});

		it("should have no response", function() {
			expect(response).toBeNull();
		});
	});
});

describe("An array", function() {
	var arr = [];

	beforeEach(function(done) {
		arr = [100, 200, 300, 400];
		done();
	});

	describe("should remove", function() {
		it("an element in the array", function() {
			var removed = arr.removeElementEqualTo(300);

			expect(removed).toEqual(300);
			expect(arr).toEqual([100, 200, 400]);
		});

		it("an element not in the array", function() {
			var removed = arr.removeElementEqualTo(800);

			expect(removed).toBeUndefined();
			expect(arr).toEqual([100, 200, 300, 400]);
		});
	});

	describe("should remove the element at the index", function() {
		it("in the array", function() {
			var removed = arr.removeAtIndex(0);

			expect(removed).toEqual(100);
			expect(arr).toEqual([200, 300, 400]);
		});

		it("outside of the array (pos)", function() {
			var removed = arr.removeAtIndex(800);

			expect(removed).toBeUndefined();
			expect(arr).toEqual([100, 200, 300, 400]);
		});
	});

	it("should insert an element at an arbitrary index", function() {
		arr.insertAtIndex(0, 3);

		expect(arr).toEqual([100, 200, 300, 0, 400]);
	});

	it("should swap elements", function() {
		var removed = arr.removeAtIndex(-1);
		arr.insertAtIndex(removed, 2);

		expect(removed).toEqual(400);
		expect(arr).toEqual([100, 200, 400, 300]);
	});
});<commit_msg>Add test for hostname for local files (file://)<commit_after>describe("A URL", function() {
	describe("that starts with http", function() {
		it("should be able to extract the domain", function() {
			expect(getDomain('http://www.google.com')).toMatch('www.google.com');
			expect(getDomain('http://www.google.com/')).toMatch('www.google.com');
			expect(getDomain('http://www.google.com/kitty')).toMatch('www.google.com');
		});

		it("should be able to extract the hostname", function() {
			expect(getDomain('http://www.google.com')).toMatch('google.com');
			expect(getDomain('http://www.google.com/')).toMatch('google.com');
			expect(getDomain('http://www.google.com/kitty')).toMatch('google.com');
		});
	});

	describe("that starts with https", function() {
		it("should be able to extract the domain", function() {
			expect(getDomain('https://www.google.com')).toMatch('www.google.com');
			expect(getDomain('https://www.google.com/')).toMatch('www.google.com');
			expect(getDomain('https://www.google.com/kitty')).toMatch('www.google.com');
		});

		it("should be able to extract the hostname", function() {
			expect(getDomain('https://www.google.com')).toMatch('google.com');
			expect(getDomain('https://www.google.com/')).toMatch('google.com');
			expect(getDomain('https://www.google.com/kitty')).toMatch('google.com');
		});
	});

	describe("that starts with file://", function() {
		it("should be able to extract the hostname", function() {
			expect(getHostname('file://username/file.html')).toMatch('localhost');
			expect(getHostname('file://more/files/to/read/here/now.txt')).toMatch('localhost');
		});
	});

	describe("that is a chrome URL", function() {
		it("should be detected with no subdirectories", function() {
			expect(isChromeURL("chrome://newtabpage"));
		});

		it("should be detected with subdirectories", function() {
			expect(isChromeURL("chrome://newtabpage/kitty/meow"));
			expect(isChromeURL("chrome://newtabpage/kitty/meow/"));
		});
	});

	describe("that is an extension URL", function() {
		var url = chrome.extension.getURL("/");

		it("should be detected with no subdirectories", function() {
			expect(isExtensionURL(url));
		});

		it("should be detected with subdirectories", function() {
			expect(isExtensionURL(url + "test"));
			expect(isExtensionURL(url + "test/"));
		});

		it("should be detected if it is the new tab page", function() {
			expect(isExtensionURL("chrome://newtab"));
			expect(isExtensionURL("chrome://newtab/"));
		})
	});
});

describe("A loop", function() {
	var answer;

	beforeEach(function(done) {
		answer = null;
		done();
	});

	it("should repeat the right number of times", function() {
		runs(function(done) {
			answer = 0;

			loop(0, 5, function(i, next) {
				answer += i;

				next();
			}, done);
		});

		runs(function(done) {
			expect(answer).toBe(10);
			done();
		});
	});

	it("should not run when the end is less than the iteration", function() {
		runs(function(done) {
			answer = 0;

			loop(5, -1, function(i, next) {
				answer += i;

				next();
			}, done);
		});

		runs(function(done) {
			expect(answer).toBe(0);
			done();
		});
	});
});

describe("An asynchronous loop", function() {
	var answer;

	beforeEach(function(done) {
		answer = null;
		done();
	});

	describe("when the end is greater than the start", function() {
		it("should repeat the right number of times", function() {
			runs(function(done) {
				answer = 0;

				async_loop(0, 5, function(iteration, callback) {
					answer += iteration;

					callback();
				}, done);
			});

			runs(function(done) {
				expect(answer).toBe(10);
				done();
			});
		});
	});

	describe("when the end is one more than the start", function() {
		it("should repeat the right number of times", function() {
			runs(function(done) {
				answer = 1;

				async_loop(0, 1, function(iteration, callback) {
					answer += iteration;

					callback();
				}, done);
			});

			runs(function(done) {
				expect(answer).toBe(1);
				done();
			});
		});
	});

	describe("when the end is less than the start", function() {
		it("should not run", function() {
			runs(function(done) {
				answer = 0;

				async_loop(5, -1, function(iteration, callback) {
					answer += iteration;

					callback();
				}, done);
			});

			runs(function(done) {
				expect(answer).toBe(0);
				done();
			});
		});
	});

	describe("when running asynchronous operations", function() {
		it("should run them in any order", function() {
			runs(function(done) {
				answer = [];

				async_loop(0, 5, function(iteration, callback) {
					setTimeout(function() {
						answer.push(iteration);

						callback();
					}, 500 - iteration * 100);
				}, done);
			});

			runs(function(done) {
				expect(answer).toEqual([4, 3, 2, 1, 0]);
				done();
			});
		});

		it("should wait for the asynchronous operations to finish", function() {
			runs(function(done) {
				answer = [];

				async_loop(0, 5, function(iteration, callback) {
					setTimeout(function() {
						answer.push(iteration);

						callback();
					});
				}, done);
			});

			runs(function(done) {
				expect(answer).toEqual([0, 1, 2, 3, 4]);
				done();
			});
		});
	});
});

describe("An HTTP request", function() {
	var server = null;
	var success, error, response;

	beforeEach(function(done) {
		server = sinon.fakeServer.create();

		success = false;
		error = false;
		response = null;
		done();
	});

	afterEach(function(done) {
		server.restore();
		done();
	});

	describe("making a request that will respond 200", function() {
		beforeEach(function(done) {
			server.respondWith("GET", "/", [200, { "Content-Type": "text/html"}, "yay"]);

			makeHTTPRequest('/', function(res, headers) {
				response = res;

				success = true;
				done();
			}, function(status) {
				error = true;
				done();
			});

			server.respond();
		});

		it("should be successful", function() {
			expect(success).toBe(true);
			expect(error).toBe(false);
		});

		it("should have the correct response", function() {
			expect(response).toEqual("yay");
		});
	});

	describe("making a request that will respond 404", function() {
		beforeEach(function(done) {
			server.respondWith("GET", "/", [404, { "Content-Type": "text/html"}, "yay"]);

			makeHTTPRequest('/', function(res, headers) {
				response = res;

				success = true;
				done();
			}, function(status) {
				error = true;
				done();
			});

			server.respond();
		});

		it("should not be successful", function() {
			expect(success).toBe(false);
			expect(error).toBe(true);
		});

		it("should have no response", function() {
			expect(response).toBeNull();
		});
	});

	describe("making a request that will respond 301", function() {
		beforeEach(function(done) {
			server.respondWith("GET", "/", [301, { "Content-Type": "text/html"}, "yay"]);

			makeHTTPRequest('/', function(res, headers) {
				response = res;

				success = true;
				done();
			}, function(status) {
				error = true;
				done();
			});

			server.respond();
		});

		it("should not be successful", function() {
			expect(success).toBe(false);
			expect(error).toBe(true);
		});

		it("should have no response", function() {
			expect(response).toBeNull();
		});
	});
});

describe("An array", function() {
	var arr = [];

	beforeEach(function(done) {
		arr = [100, 200, 300, 400];
		done();
	});

	describe("should remove", function() {
		it("an element in the array", function() {
			var removed = arr.removeElementEqualTo(300);

			expect(removed).toEqual(300);
			expect(arr).toEqual([100, 200, 400]);
		});

		it("an element not in the array", function() {
			var removed = arr.removeElementEqualTo(800);

			expect(removed).toBeUndefined();
			expect(arr).toEqual([100, 200, 300, 400]);
		});
	});

	describe("should remove the element at the index", function() {
		it("in the array", function() {
			var removed = arr.removeAtIndex(0);

			expect(removed).toEqual(100);
			expect(arr).toEqual([200, 300, 400]);
		});

		it("outside of the array (pos)", function() {
			var removed = arr.removeAtIndex(800);

			expect(removed).toBeUndefined();
			expect(arr).toEqual([100, 200, 300, 400]);
		});
	});

	it("should insert an element at an arbitrary index", function() {
		arr.insertAtIndex(0, 3);

		expect(arr).toEqual([100, 200, 300, 0, 400]);
	});

	it("should swap elements", function() {
		var removed = arr.removeAtIndex(-1);
		arr.insertAtIndex(removed, 2);

		expect(removed).toEqual(400);
		expect(arr).toEqual([100, 200, 400, 300]);
	});
});<|endoftext|>