Skip to content

Commit

Permalink
merge master into dms3-version (hand merge src/app.js to include both…
Browse files Browse the repository at this point in the history
… F.service.Group and F.service.Introspect)
  • Loading branch information
Molly Jones committed Sep 20, 2016
2 parents ac06d13 + 8cc4e9e commit af63366
Show file tree
Hide file tree
Showing 48 changed files with 1,211 additions and 598 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dist/* binary
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pids
!.bowerrc
!.gitignore
!.jscsrc
!.gitattributes

# sass
.sass-cache/
Expand Down Expand Up @@ -49,3 +50,5 @@ dist/epicenter-edge-instrumented.js
coverage/
.DS_Store
**/.DS_Store

*.orig
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"tests"
],
"dependencies": {
"jquery": "~2.1.1",
"jquery": "~3.1.0",
"cometd-jquery": "2.9.0"
},
"devDependencies": {}
Expand Down
6 changes: 3 additions & 3 deletions dist/components/assignment/assignment.js

Large diffs are not rendered by default.

2 changes: 0 additions & 2 deletions dist/components/login/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,6 @@ $(function () {
})
.then(function () {
window.location = action;
})
.done(function () {
$('.group-selection-dialog').hide();
});
});
Expand Down
492 changes: 435 additions & 57 deletions dist/epicenter.js

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions dist/epicenter.min.js

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion dist/epicenter.min.js.map

Large diffs are not rendered by default.

27 changes: 14 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,24 @@
"devDependencies": {
"browserify-istanbul": "^2.0.0",
"growl": "^1.8.1",
"grunt": "^0.4.5",
"grunt": "^1.0.1",
"grunt-browserify": "^5.0.0",
"grunt-bump": "0.0.15",
"grunt-bump": "^0.8.0",
"grunt-contrib-copy": "^1.0.0",
"grunt-contrib-jshint": "1.0.0",
"grunt-contrib-uglify": "^0.7.0",
"grunt-contrib-watch": "^0.6.1",
"grunt-conventional-changelog": "^1.1.0",
"grunt-jscs": "^2.3.0",
"grunt-contrib-uglify": "^2.0.0",
"grunt-contrib-watch": "^1.0.0",
"grunt-conventional-changelog": "^6.1.0",
"grunt-jscs": "^3.0.1",
"grunt-markdox": "^1.2.1",
"grunt-mocha-phantom-istanbul": "^0.1.1",
"husky": "^0.10.2",
"istanbul": "^0.4.3",
"jshint-stylish": "2.2.0",
"minifyify": "^6.1.3",
"uglify-js": "^2.4.15",
"grunt-contrib-copy": "^0.8.0",
"grunt-template-module": "^0.5.0"
"grunt-template-module": "^0.5.0",
"husky": "^0.11.7",
"istanbul": "^0.4.5",
"jshint-stylish": "^2.2.1",
"minifyify": "^7.3.3",
"object-assign": "^4.1.0",
"uglify-js": "^2.7.3"
},
"scripts": {
"prepush": "grunt validate"
Expand Down
42 changes: 42 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,48 @@ grunt test or grunt documentation
```
This will create an ```epicenter-edge.js``` file in ```dist/```. When you're happy with your changes do ```grunt production``` and make a pull-request to `master`.

## Development guide
Current code might not be aligned with the guide since is hard to do a library-wide refactor but we should be refactoring current code when is possible.

### Options
Options are passed and merged in most of the "layers":
- Manager constructors and/or methods
- Service constructors and/or methods
- Transport layer (with the `transport` property)

All Managers/Services constructors accept an options object but some methods do not allow override, it should be cleary documented when the method does not allow options override.

Use the `SessionManager` to automatically get the merged session and library-wide options.

### Services
Use `serviceUtils` for misc service utilities. Like generating the `serviceOptions` using the `SessionManager` and setting the `Authorization` header. Eventually all boilerplate code in the services should be removed in favor of using the `serviceUtils`.

### Tools
New code should:
- Use `require('object-assign')` "ponyfill" and avoid deep object merges as is very slow
- When deep assign needed use: `deep-assign`
- Avoid using jQuery utils methods

### Future
Eventually (maybe v2) we should try to:
- Add library-wide options that we plug into `SessionManager` (all services/managers are using it)
```javascript
F.init({ options: { account: 'acme', version: 'v2' }});
```
- Make the sync call in [configuration-service.js](src/service/configuration-service.js) async as default and add an option to make it sync (so it will be easier to older sims to update):
```javascript
F.init({ config: { syncFetch: true }, options: {...} });
```
- Remove `jQuery` as a global dependency and just require $.ajax (if possible) or replace with another node/browser library (may not be worth the effort $.ajax works fine)
- Use ES6 promises
- Be able to use ES6 imports
```javascript
import F, { RunManager } from 'epicenter-js';
import { DataService } from 'epicenter-js';
import { AuthManager } from 'epicenter-js';
```
- Try not to break documented service or manager methods

© Forio Corporation, 2014-2016. All rights reserved.


2 changes: 1 addition & 1 deletion src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ F.load = require('./env-load');
F.load();

F.util.query = require('./util/query-util');
F.util.makeSequence = require('./util/make-sequence');
F.util.run = require('./util/run-util');
F.util.classFrom = require('./util/inherit');

Expand All @@ -39,6 +38,7 @@ F.service.State = require('./service/state-api-adapter');
F.service.User = require('./service/user-api-adapter');
F.service.Member = require('./service/member-api-adapter');
F.service.Asset = require('./service/asset-api-adapter');
F.service.Group = require('./service/group-api-service');
F.service.Introspect = require('./service/introspection-api-service');

F.store.Cookie = require('./store/cookie-store');
Expand Down
2 changes: 1 addition & 1 deletion src/components/assignment/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<link rel="stylesheet" href="https://forio.com/tools/js-libs/<%= version %>/components/assignment/assignment.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js"></script>
</head>
<body>
Expand Down
2 changes: 1 addition & 1 deletion src/components/assignment/js/assignment.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ Assignment.prototype = {
this._showUpdating();
var maxUsers = +this.$('#max-users').val();
return this.worlds.autoAssignAll({ maxUsers: maxUsers })
.done(this._hideUpdating)
.then(this._hideUpdating)
.fail(this._hideUpdating)
.then(function () {
this.worlds.joinUsers();
Expand Down
2 changes: 1 addition & 1 deletion src/components/assignment/js/users-collection.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ module.exports = classFrom(Base, {
.then(function (users) {
users = _.map(users, function (u) { return _.extend(u, { groupId: groupId }); });
_this.set(users);
dtd.resolve(users, _this);
dtd.resolve(users);
});

return dtd.promise();
Expand Down
2 changes: 1 addition & 1 deletion src/components/login/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<link rel="stylesheet" href="https://forio.com/tools/js-libs/<%= version %>/components/login/login.css">

<!-- make sure to include jquery, epicenter.js and login.js -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="https://forio.com/tools/js-libs/<%= version %>/epicenter.min.js"></script>
<script src="https://forio.com/tools/js-libs/<%= version %>/components/login/login.js"></script>
</head>
Expand Down
2 changes: 0 additions & 2 deletions src/components/login/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,6 @@ $(function () {
})
.then(function () {
window.location = action;
})
.done(function () {
$('.group-selection-dialog').hide();
});
});
Expand Down
4 changes: 2 additions & 2 deletions src/env-load.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ var envLoad = function (callback) {
}
var infoUrl = host + envPath;
envPromise = $.ajax({ url: infoUrl, async: false });
envPromise.done(function (res) {
envPromise.then(function (res) {
var api = res.api;
$.extend(urlConfigService, api);
}).fail(function (res) {
// Epicenter/webserver not properly configured
// fallback to api.forio.com
$.extend(urlConfigService, { protocol: 'https', host: 'api.forio.com' });
});
return envPromise.done(callback).fail(callback);
return envPromise.then(callback).fail(callback);
};

module.exports = envLoad;
82 changes: 51 additions & 31 deletions src/managers/auth-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@
'use strict';
var AuthAdapter = require('../service/auth-api-service');
var MemberAdapter = require('../service/member-api-adapter');
var GroupService = require('../service/group-api-service');
var SessionManager = require('../store/session-manager');
var Buffer = require('buffer').Buffer;
var _pick = require('../util/object-util')._pick;
var objectAssign = require('object-assign');

var defaults = {
requiresGroup: true
Expand Down Expand Up @@ -153,40 +155,59 @@ AuthManager.prototype = $.extend(AuthManager.prototype, {
return;
}

_this.getUserGroups({ userId: userInfo.user_id, token: token }, userGroupOpts).done(function (memberInfo) {
data.userGroups = memberInfo;
var handleGroupList = function (groupList) {
data.userGroups = groupList;

var group = null;
if (memberInfo.length === 0) {
if (groupList.length === 0) {
handleGroupError('The user has no groups associated in this account', 401, data);
return;
} else if (memberInfo.length === 1) {
} else if (groupList.length === 1) {
// Select the only group
group = memberInfo[0];
} else if (memberInfo.length > 1) {
group = groupList[0];
} else if (groupList.length > 1) {
if (groupId) {
var filteredGroups = $.grep(memberInfo, function (resGroup) {
var filteredGroups = $.grep(groupList, function (resGroup) {
return resGroup.groupId === groupId;
});
group = filteredGroups.length === 1 ? filteredGroups[0] : null;
}
}

if (group) {
// A team member does not get the group members because is calling the Group API
// but it's automatically a fac user
var isFac = isTeamMember ? true : _findUserInGroup(group.members, userInfo.user_id).role === 'facilitator';
var groupData = {
'groupId': group.groupId,
'groupName': group.name,
'isFac': _findUserInGroup(group.members, userInfo.user_id).role === 'facilitator'
groupId: group.groupId,
groupName: group.name,
isFac: isFac
};
var sessionInfoWithGroup = $.extend({}, sessionInfo, groupData);
var sessionInfoWithGroup = objectAssign({}, sessionInfo, groupData);
sessionInfo.groups[project] = groupData;
_this.sessionManager.saveSession(sessionInfoWithGroup, adapterOptions);
outSuccess.apply(this, [data]);
$d.resolve(data);
} else {
handleGroupError('This user is associated with more than one group. Please specify a group id to log into and try again', 403, data);
}
}).fail($d.reject);
};

if (!isTeamMember) {
_this.getUserGroups({ userId: userInfo.user_id, token: token }, userGroupOpts)
.then(handleGroupList, $d.reject);
} else {
var opts = objectAssign({}, userGroupOpts, { token: token });
var groupService = new GroupService(opts);
groupService.getGroups({ account: adapterOptions.account, project: project })
.then(function (groups) {
// Group API returns id instead of groupId
groups.forEach(function (group) {
group.groupId = group.id;
});
handleGroupList(groups);
}, $d.reject);
}
};

adapterOptions.success = handleSuccess;
Expand Down Expand Up @@ -230,7 +251,7 @@ AuthManager.prototype = $.extend(AuthManager.prototype, {
_this.sessionManager.removeSession();
};

return this.authAdapter.logout(adapterOptions).done(removeCookieFn);
return this.authAdapter.logout(adapterOptions).then(removeCookieFn);
},

/**
Expand Down Expand Up @@ -325,24 +346,23 @@ AuthManager.prototype = $.extend(AuthManager.prototype, {
return this.sessionManager.getSession(options);
},

// (replace with /* */ comment block, to make visible in docs, once EPICENTER-1939 is complete)
//
// Add one or more groups to the current session.
//
// This method assumes that the project and group exist and the user specified in the session is part of this project and group.
//
// Returns the new session object.
//
// **Example**
//
// authMgr.addGroups({ project: 'hello-world', groupName: 'groupName', groupId: 'groupId' });
// authMgr.addGroups([{ project: 'hello-world', groupName: 'groupName', groupId: 'groupId' }, { project: ... }]);
//
// **Parameters**
// @param {object|array} `groups` (Required) The group object must contain the `project` (**Project ID**) and `groupName` properties.
// @param {string} `group.isFac` (optional) Defaults to `false`. Set to `true` if the user in the session should be a facilitator in this group.
// @param {string} `group.groupId` (optional) Defaults to undefined. Needed mostly for the Members API.
//
/*
* Adds one or more groups to the current session.
*
* This method assumes that the project and group exist and the user specified in the session is part of this project and group.
*
* Returns the new session object.
*
* **Example**
*
* authMgr.addGroups({ project: 'hello-world', groupName: 'groupName', groupId: 'groupId' });
* authMgr.addGroups([{ project: 'hello-world', groupName: 'groupName', groupId: 'groupId' }, { project: 'hello-world', groupName: '...' }]);
*
* **Parameters**
* @param {object|array} `groups` (Required) The group object must contain the `project` (**Project ID**) and `groupName` properties. If passing an array of such objects, all of the objects must contain *different* `project` (**Project ID**) values: although end users may be logged in to multiple projects at once, they may only be logged in to one group per project at a time.
* @param {string} `group.isFac` (optional) Defaults to `false`. Set to `true` if the user in the session should be a facilitator in this group.
* @param {string} `group.groupId` (optional) Defaults to undefined. Needed mostly for the Members API.
*/
addGroups: function (groups) {
var session = this.getCurrentUserSessionInfo();
var isArray = Array.isArray(groups);
Expand Down
Loading

0 comments on commit af63366

Please sign in to comment.