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 extensions.sort(function (ext1, ext2) {
107 if (ext1.loadOrder !== ext2.loadOrder) {
108 return ext1.loadOrder - ext2.loadOrder;
110 return ext1.name > ext2.name ? 1 : -1;
113 var uuids = _.map(extensions, function (ext) {
114 var sortedModels = _.sortBy(ext.codeInfo, function (codeInfo) {
115 return -1 * getVersionSize(codeInfo.version);
117 if (sortedModels[0]) {
118 return sortedModels[0].uuid;
120 X.log("Could not find uuid for extension " + ext.description);
124 uuids = _.compact(uuids); // eliminate any null values
125 var extensionPaths = _.compact(_.map(extensions, function (ext) {
126 var locationName = ext.location.indexOf("/") === 0 ?
127 path.join(ext.location, "source") :
129 return path.join(locationName, ext.name);
131 getCoreUuid('js', req.session.passport.user.organization, function (err, jsUuid) {
133 res.send({isError: true, error: err});
136 getCoreUuid('css', req.session.passport.user.organization, function (err, cssUuid) {
138 res.send({isError: true, error: err});
141 res.render(req.viewName || 'app', {
142 org: req.session.passport.user.organization,
146 extensionPaths: extensionPaths
151 var getExtensionFromRole = function (role, callback) {
152 var id = role.userAccountRole,
153 roleModel = new SYS.UserAccountRole();
155 roleModel.fetch({id: id,
156 username: X.options.databaseServer.user,
157 database: req.session.passport.user.organization,
158 success: function (model, result) {
159 var extensions = _.map(model.get("grantedExtensions"), function (ext) {
160 return ext.extension;
162 callback(null, extensions);
164 error: function (err) {
169 var extensions = _.map(user.get("grantedExtensions"), function (ext) {
170 return ext.extension;
172 // Add the extensions that the user gets from his roles
173 var userAccountRoles = user.get("grantedUserAccountRoles");
174 if (userAccountRoles.length > 0) {
175 // we're going to have to do more async calls to get all the
176 // extensions related to these roles.
177 async.map(userAccountRoles, getExtensionFromRole, function (err, results) {
179 res.send({isError: true, message: "error in extension route"});
182 // add all role-granted extensions that are not already there
183 _.each(results, function (result) {
184 _.each(result, function (newExt) {
185 var preExistingExt = _.find(extensions, function (currentExt) {
186 return currentExt.id === newExt.id;
188 if (!preExistingExt) {
189 extensions.push(newExt);
193 sendExtensions(res, extensions);
197 // no second async call necessary
198 sendExtensions(res, extensions);
203 id: req.session.passport.user.username,
204 success: fetchSuccess,
206 username: X.options.databaseServer.user,
207 database: req.session.passport.user.organization
211 exports.serveDebug = function (req, res) {
212 req.viewName = "debug";