Merge pull request #1609 from xtuple/4_5_x
[xtuple] / enyo-client / extensions / source / oauth2 / client / models / oauth2.js
1 /*jshint indent:2, curly:true, eqeqeq:true, immed:true, latedef:true,
2 newcap:true, noarg:true, regexp:true, undef:true, strict:true, trailing:true,
3 white:true*/
4 /*global XT:true, XM:true, XV:true, Backbone:true, _:true, window:true */
5
6 (function () {
7   "use strict";
8
9   XT.extensions.oauth2.initModels = function () {
10
11     //
12     // MODELS
13     //
14
15     XM.Oauth2client = XM.Model.extend({
16
17       recordType: "XM.Oauth2client",
18
19       autoFetchId: true,
20
21       defaults: function () {
22         return {
23           isActive: true
24         };
25       },
26
27       readOnlyAttributes: [
28         "clientID",
29         "clientSecret",
30         "issued",
31         "organization"
32       ],
33
34       bindEvents: function () {
35         XM.Model.prototype.bindEvents.apply(this, arguments);
36         this.on('statusChange', this.statusDidChange);
37       },
38
39       // clientType must not be editable once first saved.
40       statusDidChange: function () {
41         this.setReadOnly('clientType', this.getStatus() !== XM.Model.READY_NEW);
42
43         if (this.getStatus() === XM.Model.READY_NEW) {
44           this.set('clientID', XT.getOrganizationPath().substring(1) + "_" + XT.generateUUID());
45           // XXX the secret is only relevant for websites, but we generate it here
46           // for both because it's required to be unique on the DB level
47           // secret keys only seem to be applicable for website clients, so we might
48           // not want to make it unique
49           this.set('clientSecret', XT.generateUUID());
50           this.set('issued', new Date());
51         }
52       },
53
54       save: function (key, value, options) {
55         // Handle both `"key", value` and `{key: value}` -style arguments.
56         if (_.isObject(key) || _.isEmpty(key)) {
57           options = value;
58         }
59         options = options ? _.clone(options) : {};
60
61         var success = options.success,
62           status = this.getStatus(),
63           that = this;
64
65         options.success = function (model, resp, options) {
66           if (status === XM.Model.READY_NEW && that.get("clientType") === 'jwt bearer') {
67             // Download the private key.
68             XV.downloadURL(XT.getOrganizationPath() + '/oauth/generate-key?id=' + that.id);
69           }
70
71           if (success) { success(model, resp, options); }
72         };
73
74         // Handle both `"key", value` and `{key: value}` -style arguments.
75         if (_.isObject(key) || _.isEmpty(key)) {
76           value = options;
77         }
78
79         if (status === XM.Model.READY_NEW && that.get("clientType") === 'jwt bearer') {
80           // The order of operations for a new jwt bearer is
81           // 1. Notify the user that the download is coming
82           // 2. Save normally
83           // 3. Open the download tab.
84           //
85           // It's a little curious that 2 happens after 1, but the notify listener
86           // on the workspace gets destroyed by the time we would need it otherwise.
87           that.notify("_generatingPrivateKey".loc(), {callback: function () {
88             XM.Model.prototype.save.call(that, key, value, options);
89           }});
90         } else {
91           XM.Model.prototype.save.call(this, key, value, options);
92         }
93       }
94
95     });
96
97     XM.Oauth2clientRedirs = XM.Model.extend({
98
99       recordType: "XM.Oauth2clientRedirs",
100
101       autoFetchId: true
102
103     });
104
105     //
106     // COLLECTIONS
107     //
108
109     XM.Oauth2clientCollection = XM.Collection.extend({
110       model: XM.Oauth2client
111     });
112
113     XM.Oauth2clientRedirsCollection = XM.Collection.extend({
114       model: XM.Oauth2clientRedirs
115     });
116   };
117 }());