1 /*jshint node:true, indent:2, curly:false, eqeqeq:true, immed:true, latedef:true, newcap:true, noarg:true,
2 regexp:true, undef:true, strict:true, trailing:true, white:true */
3 /*global X:true, SYS:true, XT:true, _:true */
5 var async = require("async"),
6 path = require("path"),
7 routes = require("./routes");
13 // Get the most recent version of the core code
14 // XXX: we'll need to sometimes give older versions
15 // @param {String} language Can be "js" or "css".
17 var getCoreUuid = function (language, organization, callback) {
18 var coll = new SYS.ClientCodeRelationCollection();
20 username: X.options.databaseServer.user,
21 database: organization,
24 { attribute: "language", value: language },
25 { attribute: "extension", value: null, includeNull: true }
28 success: function (coll, res) {
29 var sortedModels = _.sortBy(coll.models, function (model) {
30 return -1 * getVersionSize(model.get("version"));
32 callback(null, sortedModels[0].get("uuid"));
38 Just get a sense of how recent a version is without the dots.
39 Higher version number string inputs will result in higher int outputs.
40 Works with three or four dot-separated numbers.
42 var getVersionSize = function (version) {
43 var versionSplit = version.split('.'), // e.g. "4.5.0-beta2".
44 versionSize = 1000000 * versionSplit[0] + // Get "4" from "4.5.0-beta2".
45 10000 * versionSplit[1] + // Get "5" from "4.5.0-beta2".
46 100 * versionSplit[2].match(/^[0-9]+/g, '')[0], // Get "0" from "0-beta2".
47 prerelease = versionSplit[2].replace(/^[0-9]+/g, ''), // Get "-beta2" from "0-beta2".
48 preRegEx = /([a-zA-Z]+)([0-9]*)/g, // Capture pre-release as ["beta2", "beta", "2"].
49 preMatch = preRegEx.exec(prerelease),
53 if (versionSplit.length > 3) {
54 versionSize += versionSplit[3];
57 if (preMatch && preMatch.length && preMatch[0] !== '') {
58 if (preMatch[1] !== '') {
59 preVersion = preMatch[1].match(/[a-zA-Z]+/g); // Get ["beta"] from ["beta2", "beta", "2"].
61 // Decrease versionSize for pre-releasees.
62 switch (preVersion[0].toLowerCase()) {
64 versionSize = versionSize - 50;
67 versionSize = versionSize - 40;
70 versionSize = versionSize - 20;
73 X.err("Cannot get pre-release version number.");
77 // Add pre-release version to versionSize.
78 if (preMatch[2] !== '') {
79 preNum = preMatch[2].match(/[0-9]+/g); // Get ["2"] from ["beta2", "beta", "2"].
80 versionSize = versionSize + parseInt(preNum);
89 Figures out what extensions the user is entitled to. Queries to determine
90 client code UUIDs for core and those extensions. Sends on to the app view
93 var serveApp = exports.serveApp = function (req, res) {
94 if (!req.session.passport.user) {
95 routes.logout(req, res);
99 var user = new SYS.User(),
100 fetchError = function (err) {
101 X.log("Extension fetch error", err);
102 res.send({isError: true, message: "Error fetching extensions"});
104 fetchSuccess = function (model, result) {
105 var sendExtensions = function (res, extensions) {
106 var filteredExtensions;
107 if (req.query.extensions) {
108 // the user is requesting to only see a certain set of extensions
109 filteredExtensions = JSON.parse(req.query.extensions);
110 extensions = extensions.filter(function (ext) {
111 return _.contains(filteredExtensions, ext.name);
115 extensions.sort(function (ext1, ext2) {
116 if (ext1.loadOrder !== ext2.loadOrder) {
117 return ext1.loadOrder - ext2.loadOrder;
119 return ext1.name > ext2.name ? 1 : -1;
122 var getLatestUuid = function (extensions, language) {
123 var uuids = _.map(extensions, function (ext) {
124 var jsModels = _.filter(ext.codeInfo, function (codeInfo) {
125 return codeInfo.language === language;
127 var sortedModels = _.sortBy(jsModels, function (codeInfo) {
128 return -1 * getVersionSize(codeInfo.version);
130 if (sortedModels[0]) {
131 return sortedModels[0].uuid;
133 X.log("Could not find js uuid for extension " + ext.description);
137 return _.compact(uuids); // eliminate any null values
139 var extJsUuids = getLatestUuid(extensions, "js");
140 var extCssUuids = getLatestUuid(extensions, "css");
141 var extensionPaths = _.compact(_.map(extensions, function (ext) {
142 var locationName = ext.location.indexOf("/") === 0 ?
143 path.join(ext.location, "source") :
145 return path.join(locationName, ext.name);
147 getCoreUuid('js', req.session.passport.user.organization, function (err, jsUuid) {
149 res.send({isError: true, error: err});
152 getCoreUuid('css', req.session.passport.user.organization, function (err, cssUuid) {
154 res.send({isError: true, error: err});
157 res.render(req.viewName || 'app', {
158 org: req.session.passport.user.organization,
161 extensionJsArray: extJsUuids,
162 extensionCssArray: extCssUuids,
163 extensionPaths: extensionPaths
168 var getExtensionFromRole = function (role, callback) {
169 var id = role.userAccountRole,
170 roleModel = new SYS.UserAccountRole();
172 roleModel.fetch({id: id,
173 username: X.options.databaseServer.user,
174 database: req.session.passport.user.organization,
175 success: function (model, result) {
176 var extensions = _.map(model.get("grantedExtensions"), function (ext) {
177 return ext.extension;
179 callback(null, extensions);
181 error: function (err) {
186 var extensions = _.map(user.get("grantedExtensions"), function (ext) {
187 return ext.extension;
189 // Add the extensions that the user gets from his roles
190 var userAccountRoles = user.get("grantedUserAccountRoles");
191 if (userAccountRoles.length > 0) {
192 // we're going to have to do more async calls to get all the
193 // extensions related to these roles.
194 async.map(userAccountRoles, getExtensionFromRole, function (err, results) {
196 res.send({isError: true, message: "error in extension route"});
199 // add all role-granted extensions that are not already there
200 _.each(results, function (result) {
201 _.each(result, function (newExt) {
202 var preExistingExt = _.find(extensions, function (currentExt) {
203 return currentExt.id === newExt.id;
205 if (!preExistingExt) {
206 extensions.push(newExt);
210 sendExtensions(res, extensions);
214 // no second async call necessary
215 sendExtensions(res, extensions);
220 id: req.session.passport.user.username,
221 success: fetchSuccess,
223 username: X.options.databaseServer.user,
224 database: req.session.passport.user.organization
228 exports.serveDebug = function (req, res) {
229 req.viewName = "debug";