vines-services 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/Gemfile +3 -0
  2. data/{README → README.md} +19 -9
  3. data/Rakefile +20 -113
  4. data/{web/coffeescripts → app/assets/javascripts}/api.coffee +1 -1
  5. data/{web/coffeescripts/init.coffee → app/assets/javascripts/application.coffee} +9 -0
  6. data/{web/coffeescripts → app/assets/javascripts}/commands.coffee +1 -1
  7. data/{web/coffeescripts → app/assets/javascripts}/files.coffee +1 -1
  8. data/{web/coffeescripts → app/assets/javascripts}/services.coffee +1 -1
  9. data/{web/coffeescripts → app/assets/javascripts}/setup.coffee +1 -1
  10. data/{web/coffeescripts → app/assets/javascripts}/systems.coffee +1 -1
  11. data/app/assets/stylesheets/application.css +9 -0
  12. data/{web → app/assets}/stylesheets/common.css +0 -0
  13. data/{web → app/assets}/stylesheets/files.css +0 -0
  14. data/{web → app/assets}/stylesheets/services.css +0 -0
  15. data/{web → app/assets}/stylesheets/setup.css +0 -0
  16. data/{web → app/assets}/stylesheets/systems.css +0 -0
  17. data/config.ru +12 -0
  18. data/lib/vines/services/command/init.rb +4 -1
  19. data/lib/vines/services/version.rb +1 -1
  20. data/{web/stylesheets/app.css → public/assets/application.css} +854 -395
  21. data/public/assets/application.js +10 -0
  22. data/{web → public}/images/default-service.png +0 -0
  23. data/{web → public}/images/linux.png +0 -0
  24. data/{web → public}/images/mac.png +0 -0
  25. data/{web → public}/images/run.png +0 -0
  26. data/{web → public}/images/windows.png +0 -0
  27. data/public/index.html +13 -0
  28. data/test/config_test.rb +1 -1
  29. data/test/priority_queue_test.rb +1 -1
  30. data/test/storage/couchdb_test.rb +1 -1
  31. data/test/vql/compiler_test.rb +1 -1
  32. data/test/vql/vql_test.rb +1 -1
  33. data/vines-services.gemspec +44 -0
  34. metadata +233 -59
  35. data/web/index.html +0 -17
  36. data/web/javascripts/api.js +0 -69
  37. data/web/javascripts/app.js +0 -2
  38. data/web/javascripts/commands.js +0 -28
  39. data/web/javascripts/files.js +0 -424
  40. data/web/javascripts/init.js +0 -27
  41. data/web/javascripts/services.js +0 -409
  42. data/web/javascripts/setup.js +0 -507
  43. data/web/javascripts/systems.js +0 -391
@@ -1,27 +0,0 @@
1
- $(function() {
2
- var buttons, icon, label, nav, pages, session;
3
- session = new Session();
4
- nav = new NavBar(session);
5
- nav.draw();
6
- buttons = {
7
- Systems: ICONS.commandline,
8
- Services: ICONS.magic,
9
- Files: ICONS.page2,
10
- Setup: ICONS.gear2,
11
- Logout: ICONS.power
12
- };
13
- for (label in buttons) {
14
- icon = buttons[label];
15
- nav.addButton(label, icon);
16
- }
17
- pages = {
18
- '/systems': new SystemsPage(session),
19
- '/services': new ServicesPage(session),
20
- '/files': new FilesPage(session),
21
- '/setup': new SetupPage(session),
22
- '/logout': new LogoutPage(session),
23
- 'default': new LoginPage(session, '/systems/')
24
- };
25
- new Router(pages).draw();
26
- return nav.select($('#nav-link-systems').parent());
27
- });
@@ -1,409 +0,0 @@
1
- var ServicesPage;
2
- var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
3
- ServicesPage = (function() {
4
- var ATTRS, MEMBERS, SERVICES, SYSTEMS, USERS;
5
- SERVICES = 'http://getvines.com/protocol/services';
6
- MEMBERS = 'http://getvines.com/protocol/services/members';
7
- SYSTEMS = 'http://getvines.com/protocol/systems';
8
- ATTRS = 'http://getvines.com/protocol/systems/attributes';
9
- USERS = 'http://getvines.com/protocol/users';
10
- function ServicesPage(session) {
11
- this.session = session;
12
- this.api = new Api(this.session);
13
- this.selectedService = null;
14
- this.validateTimeout = null;
15
- this.layout = null;
16
- this.users = [];
17
- }
18
- ServicesPage.prototype.deleteService = function(event) {
19
- var selected;
20
- this.drawBlankSlate();
21
- this.toggleForm('#remove-contact-form');
22
- selected = $("#services li[data-id='" + this.selectedService.id + "']");
23
- this.api.remove(SERVICES, this.selectedService.id, __bind(function(result) {
24
- return selected.fadeOut(200, function() {
25
- selected.remove();
26
- return this.selectedService = null;
27
- });
28
- }, this));
29
- return false;
30
- };
31
- ServicesPage.prototype.icon = function(member) {
32
- var icon, icons;
33
- icons = {
34
- darwin: 'mac.png',
35
- linux: 'linux.png',
36
- windows: 'windows.png'
37
- };
38
- icon = icons[member.os] || 'run.png';
39
- return "images/" + icon;
40
- };
41
- ServicesPage.prototype.drawMember = function(member) {
42
- var node;
43
- if (!this.editorVisible()) {
44
- return;
45
- }
46
- node = $("<li>\n <span class=\"icon\"><img src=\"" + (this.icon(member)) + "\"/></span>\n <span class=\"text\"></span>\n</li>").appendTo('#members');
47
- return $('.text', node).text(member.name);
48
- };
49
- ServicesPage.prototype.operators = function() {
50
- var node, operator, _i, _len, _ref, _results;
51
- _ref = ['like', 'not like', 'starts with', 'ends with', 'is', 'is not', '>', '>=', '<', '<=', 'and', 'or'];
52
- _results = [];
53
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
54
- operator = _ref[_i];
55
- node = $("<li data-selector=\"" + operator + "\">\n " + operator + "\n</li>").appendTo('#operators');
56
- _results.push(node.click(__bind(function(event) {
57
- var name;
58
- $('#syntax').focus();
59
- name = $(event.currentTarget).attr('data-selector');
60
- $('#syntax').val($('#syntax').val() + (" " + name + " "));
61
- return this.validateIn();
62
- }, this)));
63
- }
64
- return _results;
65
- };
66
- ServicesPage.prototype.selectService = function(node) {
67
- var id, name;
68
- id = $(node).attr('data-id');
69
- name = $(node).attr('data-name');
70
- $('#services li').removeClass('selected');
71
- $(node).addClass('selected');
72
- $('#remove-service-msg').html("Are you sure you want to remove the " + ("<strong>" + name + "</strong> service?"));
73
- $('#remove-service-form .buttons').fadeIn(200);
74
- return this.api.get(SERVICES, {
75
- id: id
76
- }, __bind(function(result) {
77
- this.selectedService = result;
78
- return this.drawEditor(result);
79
- }, this));
80
- };
81
- ServicesPage.prototype.serviceNode = function(service) {
82
- var label, node;
83
- label = service.size === 1 ? 'system' : 'systems';
84
- node = $("<li data-id=\"" + service.id + "\" data-name=\"\" data-size=\"" + service.size + "\">\n <span class=\"text\">" + service.name + "</span>\n <span class=\"count\">" + service.size + " " + label + "</span>\n</li>").appendTo('#services');
85
- node.attr('data-name', service.name);
86
- $('.text', node).text(service.name);
87
- node.click(__bind(function(event) {
88
- return this.selectService(event.currentTarget);
89
- }, this));
90
- return node;
91
- };
92
- ServicesPage.prototype.findServices = function() {
93
- return this.api.get(SERVICES, {}, __bind(function(result) {
94
- var row, _i, _len, _ref, _results;
95
- _ref = result.rows;
96
- _results = [];
97
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
98
- row = _ref[_i];
99
- _results.push(this.serviceNode(row));
100
- }
101
- return _results;
102
- }, this));
103
- };
104
- ServicesPage.prototype.findMembers = function(id) {
105
- return this.api.get(MEMBERS, {
106
- id: id
107
- }, __bind(function(result) {
108
- var row, _i, _len, _ref, _results;
109
- _ref = result.rows;
110
- _results = [];
111
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
112
- row = _ref[_i];
113
- _results.push(this.drawMember(row));
114
- }
115
- return _results;
116
- }, this));
117
- };
118
- ServicesPage.prototype.findUsers = function(syntax) {
119
- return this.api.get(USERS, {}, __bind(function(result) {
120
- var row;
121
- this.users = (function() {
122
- var _i, _len, _ref, _results;
123
- _ref = result.rows;
124
- _results = [];
125
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
126
- row = _ref[_i];
127
- if (!row.system) {
128
- _results.push(row);
129
- }
130
- }
131
- return _results;
132
- })();
133
- return this.drawUsers();
134
- }, this));
135
- };
136
- ServicesPage.prototype.attributeNode = function(attribute) {
137
- var node;
138
- node = $('<li data-name=""></li>').appendTo('#attributes');
139
- node.text(attribute);
140
- node.attr('data-name', attribute);
141
- return node.click(__bind(function(event) {
142
- var name;
143
- $('#syntax').focus();
144
- name = $(event.currentTarget).attr('data-name');
145
- $('#syntax').val($('#syntax').val() + (" " + name + " "));
146
- return this.validateIn();
147
- }, this));
148
- };
149
- ServicesPage.prototype.findAttributes = function(syntax) {
150
- return this.api.get(ATTRS, {}, __bind(function(result) {
151
- var row, _i, _len, _ref, _results;
152
- _ref = result.rows;
153
- _results = [];
154
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
155
- row = _ref[_i];
156
- _results.push(this.attributeNode(row));
157
- }
158
- return _results;
159
- }, this));
160
- };
161
- ServicesPage.prototype.validateIn = function(millis) {
162
- clearTimeout(this.validateTimeout);
163
- return this.validateTimeout = setTimeout((__bind(function() {
164
- return this.validate();
165
- }, this)), millis || 500);
166
- };
167
- ServicesPage.prototype.validate = function() {
168
- var code, prev;
169
- $('#syntax-status').text('');
170
- prev = $('#syntax').data('prev');
171
- code = $('#syntax').val().trim();
172
- $('#syntax').data('prev', code);
173
- if (!(code && code !== prev)) {
174
- return;
175
- }
176
- $('#syntax-status').text('Searching . . .');
177
- $('#members').empty();
178
- return this.api.get2(MEMBERS, code, __bind(function(result) {
179
- var row, _i, _len, _ref, _results;
180
- if (result.ok) {
181
- $('#syntax-status').text('');
182
- _ref = result.rows;
183
- _results = [];
184
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
185
- row = _ref[_i];
186
- _results.push(this.drawMember(row));
187
- }
188
- return _results;
189
- } else {
190
- return $('#syntax-status').text(result.error);
191
- }
192
- }, this));
193
- };
194
- ServicesPage.prototype.validateForm = function() {
195
- var name, valid;
196
- $('#name-error').empty();
197
- $('#unix-users-error').empty();
198
- valid = true;
199
- name = $('#name').val().trim();
200
- if (name === '') {
201
- $('#name-error').text('Name is required.');
202
- valid = false;
203
- }
204
- if (this.accounts().length === 0) {
205
- $('#unix-users-error').text('At least one user account is required.');
206
- valid = false;
207
- }
208
- return valid;
209
- };
210
- ServicesPage.prototype.accounts = function() {
211
- var accounts, u, _i, _len, _results;
212
- accounts = $('#unix-users').val().split(',');
213
- _results = [];
214
- for (_i = 0, _len = accounts.length; _i < _len; _i++) {
215
- u = accounts[_i];
216
- if (u.trim().length > 0) {
217
- _results.push(u.trim());
218
- }
219
- }
220
- return _results;
221
- };
222
- ServicesPage.prototype.save = function() {
223
- var service, users;
224
- if (!this.validateForm()) {
225
- return false;
226
- }
227
- users = $('#users :checked').map(function() {
228
- return $(this).val();
229
- }).get();
230
- service = {
231
- name: $('#name').val(),
232
- code: $('#syntax').val(),
233
- accounts: this.accounts(),
234
- users: users
235
- };
236
- if ($('#id').val().length > 0) {
237
- service['id'] = $('#id').val();
238
- }
239
- this.api.save(SERVICES, service, __bind(function(result) {
240
- var node;
241
- new Notification('Service saved successfully');
242
- result.size = $('#members').length;
243
- $('#id').val(result.id);
244
- node = $("#services li[data-id='" + result.id + "']");
245
- if (node.length === 0) {
246
- node = this.serviceNode(result);
247
- return this.selectService(node);
248
- } else {
249
- return $('.text', node).text(result.name);
250
- }
251
- }, this));
252
- return false;
253
- };
254
- ServicesPage.prototype.drawBlankSlate = function() {
255
- $('#beta').empty();
256
- $("<form id=\"blank-slate\">\n <p>\n Services are dynamically updated groups of systems based on\n criteria you define. Send a command to the service and it runs\n on every system in the group.\n </p>\n <input type=\"submit\" id=\"blank-slate-add\" value=\"Add Service\"/>\n</form>").appendTo('#beta');
257
- if (!this.api.user.permissions.services) {
258
- $('#blank-slate-add').remove();
259
- }
260
- return $('#blank-slate').submit(__bind(function() {
261
- this.drawEditor();
262
- return false;
263
- }, this));
264
- };
265
- ServicesPage.prototype.draw = function() {
266
- var fn;
267
- if (!this.session.connected()) {
268
- window.location.hash = '';
269
- return;
270
- }
271
- $('body').attr('id', 'services-page');
272
- $('#container').hide().empty();
273
- $("<div id=\"alpha\" class=\"sidebar column y-fill\">\n <h2>Services <div id=\"search-services-icon\"></div></h2>\n <div id=\"search-services-form\"></div>\n <ul id=\"services\" class=\"selectable scroll y-fill\"></ul>\n <div id=\"alpha-controls\" class=\"controls\">\n <div id=\"add-service\"></div>\n <div id=\"remove-service\"></div>\n </div>\n <form id=\"remove-service-form\" class=\"overlay\" style=\"display:none;\">\n <h2>Remove Service</h2>\n <p id=\"remove-service-msg\">Select a service in the list above to remove.</p>\n <fieldset class=\"buttons\" style=\"display:none;\">\n <input id=\"remove-service-cancel\" type=\"button\" value=\"Cancel\"/>\n <input id=\"remove-service-ok\" type=\"submit\" value=\"Remove\"/>\n </fieldset>\n </form>\n</div>\n<div id=\"beta\" class=\"primary column x-fill y-fill\"></div>\n<div id=\"charlie\" class=\"sidebar column y-fill\">\n <h2>Operators</h2>\n <ul id=\"operators\"></ul>\n <h2>Attributes <div id=\"search-attributes-icon\"></div></h2>\n <div id=\"search-attributes-form\"></div>\n <ul id=\"attributes\" class=\"y-fill scroll\"></ul>\n</div>").appendTo('#container');
274
- new Button('#add-service', ICONS.plus);
275
- new Button('#remove-service', ICONS.minus);
276
- if (!this.api.user.permissions.services) {
277
- $('#alpha-controls div').remove();
278
- }
279
- this.drawBlankSlate();
280
- $('#add-service').click(__bind(function() {
281
- return this.drawEditor();
282
- }, this));
283
- $('#remove-service').click(__bind(function() {
284
- return this.toggleForm('#remove-service-form');
285
- }, this));
286
- $('#remove-service-cancel').click(__bind(function() {
287
- return this.toggleForm('#remove-service-form');
288
- }, this));
289
- $('#remove-service-form').submit(__bind(function() {
290
- return this.deleteService();
291
- }, this));
292
- this.operators();
293
- this.findServices();
294
- this.findAttributes();
295
- this.findUsers();
296
- $('#container').show();
297
- this.layout = this.resize();
298
- fn = __bind(function() {
299
- this.layout.resize();
300
- return this.layout.resize();
301
- }, this);
302
- new Filter({
303
- list: '#services',
304
- icon: '#search-services-icon',
305
- form: '#search-services-form',
306
- attrs: ['data-name'],
307
- open: fn,
308
- close: fn
309
- });
310
- return new Filter({
311
- list: '#attributes',
312
- icon: '#search-attributes-icon',
313
- form: '#search-attributes-form',
314
- attrs: ['data-name'],
315
- open: fn,
316
- close: fn
317
- });
318
- };
319
- ServicesPage.prototype.drawEditor = function(service) {
320
- if (!this.pageVisible()) {
321
- return;
322
- }
323
- if (!service) {
324
- this.selectedService = null;
325
- $('#services li').removeClass('selected');
326
- }
327
- $('#beta').empty();
328
- $("<form id=\"editor-form\" class=\"sections y-fill scroll\">\n <input id=\"id\" type=\"hidden\"/>\n <div>\n <section>\n <h2>Service</h2>\n <fieldset>\n <label for=\"name\">Name</label>\n <input id=\"name\" type=\"text\"/>\n <p id=\"name-error\" class=\"error\"></p>\n <label for=\"syntax\">Criteria</label>\n <textarea id=\"syntax\" placeholder=\"fqdn starts with 'www.' and platform is 'mac_os_x'\"></textarea>\n <p id=\"syntax-status\"></p>\n </fieldset>\n </section>\n <section>\n <h2>Members</h2>\n <fieldset id=\"service-preview\">\n <ul id=\"members\" class=\"scroll\"></ul>\n </fieldset>\n </section>\n <section>\n <h2>Permissions</h2>\n <fieldset>\n <label>Users</label>\n <ul id=\"users\" class=\"scroll\"></ul>\n <label for=\"unix-users\">Unix Accounts</label>\n <input id=\"unix-users\" type=\"text\"/>\n <p id=\"unix-users-error\" class=\"error\"></p>\n <p class=\"hint\">Comma separated user names like: apache, postgres, root, etc.</p>\n </fieldset>\n </section>\n </div>\n</form>\n<form id=\"editor-buttons\">\n <input id=\"save\" type=\"submit\" value=\"Save\"/>\n</form>").appendTo('#beta');
329
- if (service) {
330
- this.findMembers(service.id);
331
- $('#id').val(service.id);
332
- $('#name').val(service.name);
333
- $('#syntax').val(service.code);
334
- $('#unix-users').val(service.accounts.join(', '));
335
- }
336
- if (this.users.length > 0) {
337
- this.drawUsers();
338
- }
339
- this.layout.resize();
340
- $('#name').focus();
341
- $('#syntax').change(__bind(function() {
342
- return this.validateIn();
343
- }, this));
344
- $('#syntax').keyup(__bind(function() {
345
- return this.validateIn();
346
- }, this));
347
- $('#editor-form').submit(__bind(function() {
348
- return this.save();
349
- }, this));
350
- return $('#editor-buttons').submit(__bind(function() {
351
- return this.save();
352
- }, this));
353
- };
354
- ServicesPage.prototype.drawUsers = function() {
355
- var node, user, _i, _len, _ref;
356
- if (!this.editorVisible()) {
357
- return;
358
- }
359
- $('#users').empty();
360
- _ref = this.users;
361
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
362
- user = _ref[_i];
363
- node = $("<li>\n <input id='user-" + user.jid + "' type='checkbox' value='" + user.jid + "'/>\n <label for='user-" + user.jid + "'>" + user.jid + "</label>\n</li>").appendTo('#users');
364
- if (user.jid === this.session.bareJid()) {
365
- $('input', node).prop('checked', true);
366
- }
367
- }
368
- if (this.selectedService) {
369
- return $('#users input[type="checkbox"]').val(this.selectedService.users);
370
- }
371
- };
372
- ServicesPage.prototype.toggleForm = function(form, fn) {
373
- form = $(form);
374
- $('form.overlay').each(function() {
375
- if (this.id !== form.attr('id')) {
376
- return $(this).hide();
377
- }
378
- });
379
- if (form.is(':hidden')) {
380
- if (fn) {
381
- fn();
382
- }
383
- return form.fadeIn(100);
384
- } else {
385
- return form.fadeOut(100, function() {
386
- form[0].reset();
387
- if (fn) {
388
- return fn();
389
- }
390
- });
391
- }
392
- };
393
- ServicesPage.prototype.pageVisible = function() {
394
- return $('#services-page').length > 0;
395
- };
396
- ServicesPage.prototype.editorVisible = function() {
397
- return $('#services-page #editor-form').length > 0;
398
- };
399
- ServicesPage.prototype.resize = function() {
400
- var a, b, c;
401
- a = $('#alpha');
402
- b = $('#beta');
403
- c = $('#charlie');
404
- return new Layout(function() {
405
- return c.css('left', a.width() + b.width());
406
- });
407
- };
408
- return ServicesPage;
409
- })();
@@ -1,507 +0,0 @@
1
- var SetupPage;
2
- var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
3
- SetupPage = (function() {
4
- var SERVICES, SYSTEMS, USERS;
5
- SERVICES = 'http://getvines.com/protocol/services';
6
- SYSTEMS = 'http://getvines.com/protocol/systems';
7
- USERS = 'http://getvines.com/protocol/users';
8
- function SetupPage(session) {
9
- this.session = session;
10
- this.api = new Api(this.session);
11
- this.layout = null;
12
- this.selected = null;
13
- this.services = [];
14
- this.users = [];
15
- }
16
- SetupPage.prototype.findSystem = function(name) {
17
- return this.api.get(SYSTEMS, {
18
- name: name
19
- }, __bind(function(result) {
20
- return this.drawSystemInfo(result);
21
- }, this));
22
- };
23
- SetupPage.prototype.findServices = function() {
24
- return this.api.get(SERVICES, {}, __bind(function(result) {
25
- this.services = result.rows;
26
- return this.drawServices();
27
- }, this));
28
- };
29
- SetupPage.prototype.drawServices = function() {
30
- var node, service, _i, _len, _ref;
31
- if ($('#setup-page #services').length === 0) {
32
- return;
33
- }
34
- $('#services').empty();
35
- _ref = this.services;
36
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
37
- service = _ref[_i];
38
- node = $("<li>\n <input id='service-" + service.id + "' type='checkbox' value='" + service.id + "'/>\n <label for='service-" + service.id + "'></label>\n</li>").appendTo('#services');
39
- $('label', node).text(service.name);
40
- }
41
- if (this.selected) {
42
- $('#services input[type="checkbox"]').val(this.selected.services);
43
- }
44
- if (this.selected && !this.api.user.permissions.services) {
45
- return $('#services input[type="checkbox"]').prop('disabled', true);
46
- }
47
- };
48
- SetupPage.prototype.findUsers = function() {
49
- return this.api.get(USERS, {}, __bind(function(result) {
50
- this.users = result.rows;
51
- return this.drawUsers();
52
- }, this));
53
- };
54
- SetupPage.prototype.drawUsers = function() {
55
- var systems, user, _i, _len, _ref, _results;
56
- if ($('#setup-page #users').length === 0) {
57
- return;
58
- }
59
- $('#users').empty();
60
- systems = $('#systems-nav').hasClass('selected');
61
- _ref = this.users;
62
- _results = [];
63
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
64
- user = _ref[_i];
65
- _results.push(user.system === systems ? this.userNode(user) : void 0);
66
- }
67
- return _results;
68
- };
69
- SetupPage.prototype.userNode = function(user) {
70
- var name, node;
71
- node = $("<li data-name=\"\" data-jid=\"" + user.jid + "\" id=\"" + user.jid + "\">\n <span class=\"text\"></span>\n <span class=\"jid\">" + user.jid + "</span>\n</li>").appendTo('#users');
72
- name = this.userName(user);
73
- $('.text', node).text(name);
74
- node.attr('data-name', name);
75
- node.click(__bind(function(event) {
76
- return this.selectUser(event.currentTarget);
77
- }, this));
78
- return node;
79
- };
80
- SetupPage.prototype.userName = function(user) {
81
- return user.name || user.jid.split('@')[0];
82
- };
83
- SetupPage.prototype.selectUser = function(node) {
84
- var jid, name;
85
- jid = $(node).attr('data-jid');
86
- name = $(node).attr('data-name');
87
- $('#users li').removeClass('selected');
88
- $(node).addClass('selected');
89
- $('#remove-user-msg').html("Are you sure you want to remove " + ("<strong>" + name + "</strong>?"));
90
- $('#remove-user-form .buttons').fadeIn(200);
91
- return this.api.get(USERS, {
92
- jid: jid
93
- }, __bind(function(result) {
94
- this.selected = result;
95
- if (result.system) {
96
- return this.drawSystemEditor(result);
97
- } else {
98
- return this.drawUserEditor(result);
99
- }
100
- }, this));
101
- };
102
- SetupPage.prototype.removeUser = function() {
103
- var selected;
104
- this.toggleForm('#remove-user-form');
105
- selected = $("#users li[data-jid='" + this.selected.jid + "']");
106
- return this.api.remove(USERS, this.selected.jid, __bind(function(result) {
107
- return selected.fadeOut(200, __bind(function() {
108
- var u;
109
- this.users = (function() {
110
- var _i, _len, _ref, _results;
111
- _ref = this.users;
112
- _results = [];
113
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
114
- u = _ref[_i];
115
- if (u.jid !== this.selected.jid) {
116
- _results.push(u);
117
- }
118
- }
119
- return _results;
120
- }).call(this);
121
- selected.remove();
122
- this.selected = null;
123
- if ($('#users-nav').hasClass('selected')) {
124
- return this.drawUserBlankSlate();
125
- } else {
126
- return this.drawSystemBlankSlate();
127
- }
128
- }, this));
129
- }, this));
130
- };
131
- SetupPage.prototype.selectTask = function(event) {
132
- this.selected = null;
133
- $('#setup li').removeClass('selected secondary');
134
- $(event.currentTarget).addClass('selected secondary');
135
- $('form.overlay').fadeOut(100, __bind(function() {
136
- return this.layout.resize();
137
- }, this));
138
- switch ($(event.currentTarget).attr('id')) {
139
- case 'users-nav':
140
- $('#beta-header').text('Users');
141
- $('#remove-user-form h2').text('Remove User');
142
- $('#remove-user-msg').html("Select a user to delete.");
143
- $('#remove-user-form .buttons').hide();
144
- this.drawUsers();
145
- this.drawUserBlankSlate();
146
- return this.toggleBetaControls(this.api.user.permissions.users);
147
- case 'systems-nav':
148
- $('#beta-header').text('Systems');
149
- $('#remove-user-form h2').text('Remove System');
150
- $('#remove-user-msg').html("Select a system to delete.");
151
- $('#remove-user-form .buttons').hide();
152
- this.drawUsers();
153
- this.drawSystemBlankSlate();
154
- return this.toggleBetaControls(this.api.user.permissions.systems);
155
- }
156
- };
157
- SetupPage.prototype.toggleBetaControls = function(show) {
158
- if (show) {
159
- return $('#beta-controls div').show();
160
- } else {
161
- return $('#beta-controls div').hide();
162
- }
163
- };
164
- SetupPage.prototype.toggleForm = function(form, fn) {
165
- form = $(form);
166
- $('form.overlay').each(function() {
167
- if (this.id !== form.attr('id')) {
168
- return $(this).hide();
169
- }
170
- });
171
- if (form.is(':hidden')) {
172
- if (fn) {
173
- fn();
174
- }
175
- return form.fadeIn(100);
176
- } else {
177
- return form.fadeOut(100, __bind(function() {
178
- form[0].reset();
179
- this.layout.resize();
180
- if (fn) {
181
- return fn();
182
- }
183
- }, this));
184
- }
185
- };
186
- SetupPage.prototype.validateUser = function() {
187
- var node, password1, password2, valid;
188
- $('#user-name-error').empty();
189
- $('#password-error').empty();
190
- valid = true;
191
- password1 = $('#password1').val().trim();
192
- password2 = $('#password2').val().trim();
193
- if (this.selected) {
194
- if (password2.length > 0 && password2.length < 8) {
195
- $('#password-error').text('Password must be at least 8 characters.');
196
- valid = false;
197
- }
198
- if (this.session.bareJid() !== this.selected.jid) {
199
- if (password1 !== password2) {
200
- $('#password-error').text('Passwords must match.');
201
- valid = false;
202
- }
203
- }
204
- } else {
205
- node = $('#user-name').val().trim();
206
- if (node === '') {
207
- $('#user-name-error').text('User name is required.');
208
- valid = false;
209
- }
210
- if (node.match(/[\s"&'\/:<>@]/)) {
211
- $('#user-name-error').text('User name contains forbidden characters.');
212
- valid = false;
213
- }
214
- if (password1.length === 0 || password2.length === 0) {
215
- $('#password-error').text('Password is required.');
216
- valid = false;
217
- }
218
- if (password1 !== password2) {
219
- $('#password-error').text('Passwords must match.');
220
- valid = false;
221
- }
222
- if (password2.length < 8) {
223
- $('#password-error').text('Password must be at least 8 characters.');
224
- valid = false;
225
- }
226
- }
227
- return valid;
228
- };
229
- SetupPage.prototype.saveUser = function() {
230
- var user;
231
- if (!this.validateUser()) {
232
- return false;
233
- }
234
- user = {
235
- jid: $('#jid').val(),
236
- username: $('#user-name').val(),
237
- name: $('#name').val(),
238
- password1: $('#password1').val(),
239
- password2: $('#password2').val(),
240
- services: $('#services :checked').map(function() {
241
- return $(this).val();
242
- }).get(),
243
- permissions: {
244
- systems: $('#perm-systems').prop('checked'),
245
- services: $('#perm-services').prop('checked'),
246
- files: $('#perm-files').prop('checked'),
247
- users: $('#perm-users').prop('checked')
248
- }
249
- };
250
- this.api.save(USERS, user, __bind(function(result) {
251
- var node, selected, u;
252
- new Notification('User saved successfully');
253
- $('#jid').val(result.jid);
254
- node = $("#users li[data-jid='" + result.jid + "']");
255
- if (node.length === 0) {
256
- this.users.push(result);
257
- node = this.userNode(result);
258
- return this.selectUser(node);
259
- } else {
260
- selected = ((function() {
261
- var _i, _len, _ref, _results;
262
- _ref = this.users;
263
- _results = [];
264
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
265
- u = _ref[_i];
266
- if (u.jid === result.jid) {
267
- _results.push(u);
268
- }
269
- }
270
- return _results;
271
- }).call(this))[0];
272
- selected.name = this.userName(result);
273
- return $('.text', node).text(this.userName(result));
274
- }
275
- }, this));
276
- return false;
277
- };
278
- SetupPage.prototype.validateSystem = function() {
279
- var node, valid;
280
- $('#user-name-error').empty();
281
- valid = true;
282
- node = $('#user-name').val().trim();
283
- if (!this.selected) {
284
- if (node === '') {
285
- $('#user-name-error').text('Hostname is required.');
286
- valid = false;
287
- }
288
- if (node.match(/[\s"&'\/:<>@]/)) {
289
- $('#user-name-error').text('Hostname contains forbidden characters.');
290
- valid = false;
291
- }
292
- }
293
- return valid;
294
- };
295
- SetupPage.prototype.saveSystem = function() {
296
- var user;
297
- if (!this.validateSystem()) {
298
- return false;
299
- }
300
- user = {
301
- jid: $('#jid').val(),
302
- username: $('#user-name').val(),
303
- password1: $('#password1').val(),
304
- password2: $('#password1').val(),
305
- system: true
306
- };
307
- this.api.save(USERS, user, __bind(function(result) {
308
- var node;
309
- new Notification('System saved successfully');
310
- $('#jid').val(result.jid);
311
- node = $("#users li[data-jid='" + result.jid + "']");
312
- if (node.length === 0) {
313
- this.users.push(result);
314
- node = this.userNode(result);
315
- return this.selectUser(node);
316
- } else {
317
- this.selected.name = result.name;
318
- return $('.text', node).text(result.name);
319
- }
320
- }, this));
321
- return false;
322
- };
323
- SetupPage.prototype.rand = function() {
324
- return Math.floor(Math.random() * 16);
325
- };
326
- SetupPage.prototype.token = function() {
327
- var i;
328
- return ((function() {
329
- var _results;
330
- _results = [];
331
- for (i = 0; i <= 127; i++) {
332
- _results.push(this.rand().toString(16));
333
- }
334
- return _results;
335
- }).call(this)).join('');
336
- };
337
- SetupPage.prototype.drawUserBlankSlate = function() {
338
- var msg;
339
- $('#charlie').empty();
340
- msg = this.api.user.permissions.users ? 'Select a user account to update or add a new user.' : 'Select a user account to update.';
341
- $("<form id=\"blank-slate\">\n <p>" + msg + "</p>\n <input type=\"submit\" id=\"blank-slate-add\" value=\"Add User\"/>\n</form>").appendTo('#charlie');
342
- if (!this.api.user.permissions.users) {
343
- $('#blank-slate-add').remove();
344
- }
345
- return $('#blank-slate').submit(__bind(function() {
346
- this.drawUserEditor();
347
- return false;
348
- }, this));
349
- };
350
- SetupPage.prototype.drawSystemBlankSlate = function() {
351
- $('#charlie').empty();
352
- $("<form id=\"blank-slate\">\n <p>\n Systems need a user account before they can connect and\n authenticate with the chat server.\n </p>\n <input type=\"submit\" id=\"blank-slate-add\" value=\"Add System\"/>\n</form>").appendTo('#charlie');
353
- if (!this.api.user.permissions.systems) {
354
- $('#blank-slate-add').remove();
355
- }
356
- return $('#blank-slate').submit(__bind(function() {
357
- this.drawSystemEditor();
358
- return false;
359
- }, this));
360
- };
361
- SetupPage.prototype.draw = function() {
362
- var fn;
363
- if (!this.session.connected()) {
364
- window.location.hash = '';
365
- return;
366
- }
367
- $('body').attr('id', 'setup-page');
368
- $('#container').hide().empty();
369
- $("<div id=\"alpha\" class=\"sidebar column y-fill\">\n <h2>Setup</h2>\n <ul id=\"setup\" class=\"selectable scroll y-fill\">\n <li id=\"users-nav\" class='selected secondary'>\n <span class=\"text\">Users</span>\n </li>\n <li id=\"systems-nav\">\n <span class=\"text\">Systems</span>\n </li>\n </ul>\n <div id=\"alpha-controls\" class=\"controls\"></div>\n</div>\n<div id=\"beta\" class=\"sidebar column y-fill\">\n <h2><span id=\"beta-header\">Users</span> <div id=\"search-users-icon\"></div></h2>\n <div id=\"search-users-form\"></div>\n <ul id=\"users\" class=\"selectable scroll y-fill\"></ul>\n <form id=\"remove-user-form\" class=\"overlay\" style=\"display:none;\">\n <h2>Remove User</h2>\n <p id=\"remove-user-msg\">Select a user to delete.</p>\n <fieldset class=\"buttons\" style=\"display:none;\">\n <input id=\"remove-user-cancel\" type=\"button\" value=\"Cancel\"/>\n <input id=\"remove-user-ok\" type=\"submit\" value=\"Remove\"/>\n </fieldset>\n </form>\n <div id=\"beta-controls\" class=\"controls\">\n <div id=\"add-user\"></div>\n <div id=\"remove-user\"></div>\n </div>\n</div>\n<div id=\"charlie\" class=\"primary column x-fill y-fill\"></div>").appendTo('#container');
370
- this.drawUserBlankSlate();
371
- $('#setup li').click(__bind(function(event) {
372
- return this.selectTask(event);
373
- }, this));
374
- this.findUsers();
375
- this.findServices();
376
- $('#container').show();
377
- this.layout = this.resize();
378
- new Button('#add-user', ICONS.plus);
379
- new Button('#remove-user', ICONS.minus);
380
- if (!this.api.user.permissions.users) {
381
- $('#beta-controls div').hide();
382
- }
383
- if (!this.api.user.permissions.systems) {
384
- $('#systems-nav').hide();
385
- }
386
- $('#add-user').click(__bind(function() {
387
- if ($('#users-nav').hasClass('selected')) {
388
- return this.drawUserEditor();
389
- } else {
390
- return this.drawSystemEditor();
391
- }
392
- }, this));
393
- $('#remove-user').click(__bind(function() {
394
- return this.toggleForm('#remove-user-form');
395
- }, this));
396
- $('#remove-user-cancel').click(__bind(function() {
397
- return this.toggleForm('#remove-user-form');
398
- }, this));
399
- $('#remove-user-form').submit(__bind(function() {
400
- this.removeUser();
401
- return false;
402
- }, this));
403
- fn = __bind(function() {
404
- this.layout.resize();
405
- return this.layout.resize();
406
- }, this);
407
- return new Filter({
408
- list: '#users',
409
- icon: '#search-users-icon',
410
- form: '#search-users-form',
411
- attrs: ['data-jid', 'data-name'],
412
- open: fn,
413
- close: fn
414
- });
415
- };
416
- SetupPage.prototype.drawUserEditor = function(user) {
417
- var name, _i, _len, _ref;
418
- if (!user) {
419
- this.selected = null;
420
- $('#users li').removeClass('selected');
421
- }
422
- $('#charlie').empty();
423
- $("<form id=\"editor-form\" class=\"sections y-fill scroll\">\n <div>\n <section>\n <h2>User</h2>\n <fieldset id=\"jid-fields\">\n <input id=\"jid\" type=\"hidden\" value=\"\"/>\n <label for=\"name\">Real Name</label>\n <input id=\"name\" type=\"text\" maxlength=\"1024\"/>\n </fieldset>\n </section>\n <section>\n <h2>Password</h2>\n <fieldset>\n <label id=\"password1-label\" for=\"password1\">Current Password</label>\n <input id=\"password1\" type=\"password\" maxlength=\"1024\"/>\n <label id=\"password2-label\" for=\"password2\">New Password</label>\n <input id=\"password2\" type=\"password\" maxlength=\"1024\"/>\n <p id=\"password-error\" class=\"error\"></p>\n </fieldset>\n </section>\n <section>\n <h2>Permissions</h2>\n <fieldset>\n <label>Manage</label>\n <ul id=\"permissions\">\n <li>\n <input id=\"perm-systems\" type=\"checkbox\" value=\"systems\"/>\n <label for=\"perm-systems\">Systems</label>\n </li>\n <li>\n <input id=\"perm-services\" type=\"checkbox\" value=\"services\"/>\n <label for=\"perm-services\">Services</label>\n </li>\n <li>\n <input id=\"perm-users\" type=\"checkbox\" value=\"users\"/>\n <label for=\"perm-users\">Users</label>\n </li>\n <li>\n <input id=\"perm-files\" type=\"checkbox\" value=\"files\"/>\n <label for=\"perm-files\">Files</label>\n </li>\n </ul>\n </fieldset>\n </section>\n <section>\n <h2>Services</h2>\n <fieldset>\n <label>Access To</label>\n <ul id=\"services\" class=\"scroll\"></ul>\n </fieldset>\n </section>\n </div>\n</form>\n<form id=\"editor-buttons\">\n <input id=\"save\" type=\"submit\" value=\"Save\"/>\n</form>").appendTo('#charlie');
424
- if (user) {
425
- $("<label>Account Name</label>\n<p>" + user.jid + "</p>").prependTo('#jid-fields');
426
- $('#name').focus();
427
- if (this.session.bareJid() !== user.jid) {
428
- $('#password1-label').text('Password');
429
- $('#password2-label').text('Password Again');
430
- }
431
- $('#jid').val(user.jid);
432
- $('#name').val(user.name);
433
- $('#user-name').val(user.jid.split('@')[0]);
434
- _ref = 'services systems files users'.split(' ');
435
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
436
- name = _ref[_i];
437
- if (user.permissions[name]) {
438
- $("#perm-" + name).prop('checked', true);
439
- }
440
- if (this.session.bareJid() === user.jid) {
441
- $("#perm-" + name).prop('disabled', true);
442
- }
443
- }
444
- } else {
445
- $("<label for=\"user-name\">User Name</label>\n<input id=\"user-name\" type=\"text\" maxlength=\"1023\"/>\n<p id=\"user-name-error\" class=\"error\"></p>").prependTo('#jid-fields');
446
- $('#password1-label').text('Password');
447
- $('#password2-label').text('Password Again');
448
- $('#user-name').focus();
449
- }
450
- if (this.services.length > 0) {
451
- this.drawServices();
452
- }
453
- this.layout.resize();
454
- $('#editor-form').submit(__bind(function() {
455
- return this.saveUser();
456
- }, this));
457
- return $('#editor-buttons').submit(__bind(function() {
458
- return this.saveUser();
459
- }, this));
460
- };
461
- SetupPage.prototype.drawSystemEditor = function(user) {
462
- if (!user) {
463
- this.selected = null;
464
- $('#users li').removeClass('selected');
465
- }
466
- $('#charlie').empty();
467
- $("<form id=\"editor-form\" class=\"sections y-fill scroll\">\n <div>\n <section>\n <h2>System</h2>\n <fieldset id=\"jid-fields\">\n <input id=\"jid\" type=\"hidden\" value=\"\"/>\n <label id=\"password1-label\" for=\"password1\">Authentication Token</label>\n <div id=\"token-container\">\n <input id=\"password1\" type=\"text\" readonly placeholder=\"Press Generate to create a new token\"/>\n <input id=\"new-token\" type=\"button\" value=\"Generate\"/>\n </div>\n </fieldset>\n </section>\n <section id=\"info\">\n <h2>Info</h2>\n <fieldset>\n <label>Platform</label>\n <p id=\"info-platform\">-</p>\n <label>Hostname</label>\n <p id=\"info-fqdn\">-</p>\n <label>IP Address</label>\n <p id=\"info-ip\">-</p>\n <label>MAC Address</label>\n <p id=\"info-mac\">-</p>\n </fieldset>\n </section>\n </div>\n</form>\n<form id=\"editor-buttons\">\n <input id=\"save\" type=\"submit\" value=\"Save\"/>\n</form>").appendTo('#charlie');
468
- $('#new-token').click(__bind(function() {
469
- return $('#password1').val(this.token());
470
- }, this));
471
- if (user) {
472
- this.findSystem(user.jid.split('@')[0]);
473
- }
474
- if (user) {
475
- $("<label>Account Name</label>\n<p>" + user.jid + "</p>").prependTo('#jid-fields');
476
- $('#jid').val(user.jid);
477
- $('#user-name').val(user.jid.split('@')[0]);
478
- } else {
479
- $("<label for=\"user-name\">Hostname</label>\n<input id=\"user-name\" type=\"text\" maxlength=\"1023\"/>\n<p id=\"user-name-error\" class=\"error\"></p>").prependTo('#jid-fields');
480
- $('#user-name').focus();
481
- $('#password1').val(this.token());
482
- }
483
- this.layout.resize();
484
- $('#editor-form').submit(__bind(function() {
485
- return this.saveSystem();
486
- }, this));
487
- return $('#editor-buttons').submit(__bind(function() {
488
- return this.saveSystem();
489
- }, this));
490
- };
491
- SetupPage.prototype.drawSystemInfo = function(system) {
492
- $('#info-platform').text(system.platform);
493
- $('#info-fqdn').text(system.fqdn);
494
- $('#info-ip').text(system.ipaddress);
495
- return $('#info-mac').text(system.macaddress);
496
- };
497
- SetupPage.prototype.resize = function() {
498
- var a, b, c;
499
- a = $('#alpha');
500
- b = $('#beta');
501
- c = $('#charlie');
502
- return new Layout(function() {
503
- return c.css('left', a.outerWidth() + b.outerWidth());
504
- });
505
- };
506
- return SetupPage;
507
- })();