auth 0.0.9 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +19 -162
- package/index.js +78 -0
- package/package.json +22 -27
- package/.cupboard +0 -2
- package/.npmignore +0 -2
- package/browser/account.js +0 -70
- package/browser/index.js +0 -13
- package/docs/issues.md +0 -4
- package/docs/pseudo-1.js +0 -19
- package/examples/ex1.js +0 -72
- package/examples/ex2.js +0 -62
- package/examples/models.js +0 -17
- package/examples/plugin-1.js +0 -14
- package/examples/pseduo.js +0 -6
- package/examples/pseudo-2.js +0 -2
- package/examples/pseudo-3.js +0 -61
- package/lib/access.js +0 -18
- package/lib/http/middleware/index.js +0 -31
- package/lib/http/routes/index.js +0 -152
- package/lib/http/routes/lostPassword.js +0 -121
- package/lib/http/routes/reqOutcome.js +0 -10
- package/lib/index.js +0 -65
- package/lib/mixin/ownableModel.js +0 -118
- package/lib/models/account.js +0 -281
- package/lib/models/lostPassword.js +0 -28
- package/lib/models/token.js +0 -298
- package/models.md +0 -7
package/lib/models/account.js
DELETED
|
@@ -1,281 +0,0 @@
|
|
|
1
|
-
var access = require("../access"),
|
|
2
|
-
crypto = require("crypto"),
|
|
3
|
-
_ = require("underscore"),
|
|
4
|
-
access = require("../access"),
|
|
5
|
-
Token = require("./token"),
|
|
6
|
-
outcome = require("outcome"),
|
|
7
|
-
step = require("step"),
|
|
8
|
-
dsync = require("dsync"),
|
|
9
|
-
structr = require("structr"),
|
|
10
|
-
outcome = require("outcome"),
|
|
11
|
-
comerr = require("comerr"),
|
|
12
|
-
verify = require("verify")();
|
|
13
|
-
|
|
14
|
-
exports.model = function(options) {
|
|
15
|
-
|
|
16
|
-
var database = options.connection;
|
|
17
|
-
|
|
18
|
-
Token.model(database);
|
|
19
|
-
|
|
20
|
-
var Schema = database.base.Schema,
|
|
21
|
-
ObjectId = Schema.Types.ObjectId;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
verify.register("password", "Invalid password. Must be at least 6 chars.").len(6);
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
*/
|
|
28
|
-
|
|
29
|
-
var Account = new Schema({
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
*/
|
|
33
|
-
|
|
34
|
-
validated: { type: Boolean, default: false },
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
*/
|
|
38
|
-
|
|
39
|
-
validatedAt: { type: Date, default: Date.now },
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
*/
|
|
43
|
-
|
|
44
|
-
validationKey: { type: String, default: function() {
|
|
45
|
-
return Date.now() + "_" + Math.round(Math.random()*44332482393);
|
|
46
|
-
}},
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
*/
|
|
50
|
-
|
|
51
|
-
password: { type: String, required: true, set: hashPass, select: false, default: randomPass },
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
*/
|
|
55
|
-
|
|
56
|
-
createdAt: { type: Date, default: Date.now }
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
Account.publicMethods = ["getMainToken", "createToken"];
|
|
60
|
-
|
|
61
|
-
Account.plugin(dsync.schema);
|
|
62
|
-
Account.add(options.fields || {});
|
|
63
|
-
|
|
64
|
-
var authFields;
|
|
65
|
-
|
|
66
|
-
if(!(authFields = options.authFields)) {
|
|
67
|
-
Account.add({ email: { type: String, required: true, index: { unique: true }} });
|
|
68
|
-
authFields = ["email", "password"];
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* makes this account the owner of the target item. NOT used
|
|
74
|
-
* for querying since mongodb cannot do deep object searching
|
|
75
|
-
*/
|
|
76
|
-
|
|
77
|
-
Account.methods.ownItem = function(item, acc) {
|
|
78
|
-
if(!item.owners) item.owners = [];
|
|
79
|
-
var self = this;
|
|
80
|
-
|
|
81
|
-
if(!acc) {
|
|
82
|
-
acc = access.all(false);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if(!(acc instanceof Array)) {
|
|
86
|
-
acc = [acc];
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
if(!item.owners.length) {
|
|
91
|
-
acc.push(access.SUPER); //owner
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if(this.isItemOwner(item)) return;
|
|
95
|
-
|
|
96
|
-
item.owners.push({
|
|
97
|
-
account: self._id,
|
|
98
|
-
access: acc
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
*/
|
|
104
|
-
|
|
105
|
-
Account.methods.shareItem = Account.methods.ownItem;
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
*/
|
|
109
|
-
|
|
110
|
-
Account.methods.disownItem = function(item) {
|
|
111
|
-
console.log(item.owners.remove);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
*/
|
|
116
|
-
|
|
117
|
-
Account.methods.lockdownItem = function(item) {
|
|
118
|
-
item._account = this;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* returns true / false if authorized for the given action
|
|
123
|
-
*/
|
|
124
|
-
|
|
125
|
-
Account.methods.authorized = function(item, access) {
|
|
126
|
-
|
|
127
|
-
//MUST
|
|
128
|
-
return this.isItemOwner(item, access) && (this.token ? this.token.authorized(item, access) : true);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* dead simple flow-control function. Use it like this:
|
|
133
|
-
* if(!user.hasItemAccess(item)) return user.unauthorized(callback);
|
|
134
|
-
*/
|
|
135
|
-
|
|
136
|
-
Account.methods.unauthorized = function(callback) {
|
|
137
|
-
|
|
138
|
-
var err = new comerr.Unauthorized();
|
|
139
|
-
|
|
140
|
-
return arguments.length ? callback(err) : err;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* returns true
|
|
146
|
-
*/
|
|
147
|
-
|
|
148
|
-
Account.methods.isItemOwner = function(item, acc) {
|
|
149
|
-
|
|
150
|
-
if(!acc) acc = access.all(true);
|
|
151
|
-
if(!(acc instanceof Array)) acc = [acc];
|
|
152
|
-
|
|
153
|
-
var self = this;
|
|
154
|
-
//first check if the owner exists. If
|
|
155
|
-
return !!_.find(item.owners, function(owner) {
|
|
156
|
-
return String(owner.account) == String(self._id) &&
|
|
157
|
-
!!_.intersection(acc, owner.access).length;
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* wraps owner tags around a query
|
|
164
|
-
*/
|
|
165
|
-
|
|
166
|
-
Account.methods.addToSearch = function(query, access) {
|
|
167
|
-
|
|
168
|
-
if(arguments.length === 1 && ((typeof query === "string") || (query instanceof Array))) {
|
|
169
|
-
access = query;
|
|
170
|
-
query = {};
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
if(!query) query = {};
|
|
174
|
-
|
|
175
|
-
var oaccount,
|
|
176
|
-
oaccess,
|
|
177
|
-
search = {
|
|
178
|
-
"owners.account": this._id,
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
//do?
|
|
182
|
-
/*if(!access) {
|
|
183
|
-
access = "SUPER";
|
|
184
|
-
}*/
|
|
185
|
-
|
|
186
|
-
//TODO - make
|
|
187
|
-
if(access) {
|
|
188
|
-
search["owners.access"] = access;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
return _.extend(query, search);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* returns the main account token
|
|
196
|
-
*/
|
|
197
|
-
|
|
198
|
-
Account.methods.getMainToken = function(callback) {
|
|
199
|
-
this.model("tokens").getMainToken(this, callback);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
*/
|
|
204
|
-
|
|
205
|
-
Account.methods.createToken = function(options, callback) {
|
|
206
|
-
this.model("tokens").createToken(this, options, callback);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
*/
|
|
211
|
-
|
|
212
|
-
Account.statics.signup = function(acc, callback) {
|
|
213
|
-
var Account = this;
|
|
214
|
-
|
|
215
|
-
if(!verify.check(acc).onError(callback).has("email", "password").success) return;
|
|
216
|
-
|
|
217
|
-
var on = outcome.error(callback);
|
|
218
|
-
|
|
219
|
-
//email must be lower case - it generally is. What if they're signing up on an apple device?
|
|
220
|
-
acc.email = acc.email.toLowerCase();
|
|
221
|
-
|
|
222
|
-
step(
|
|
223
|
-
function() {
|
|
224
|
-
Account.findOne({ email: acc.email }, this);
|
|
225
|
-
},
|
|
226
|
-
on.success(function(account) {
|
|
227
|
-
if(account) return callback(new comerr.AlreadyExists("That account name is already taken."));
|
|
228
|
-
new Account(acc).save(this);
|
|
229
|
-
}),
|
|
230
|
-
on.success(function(account) {
|
|
231
|
-
callback(null, account);
|
|
232
|
-
Account.emit("signup", account);
|
|
233
|
-
})
|
|
234
|
-
);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
/**
|
|
238
|
-
*/
|
|
239
|
-
|
|
240
|
-
Account.statics.login = function(credentials, callback) {
|
|
241
|
-
|
|
242
|
-
var Token = this.model("tokens");
|
|
243
|
-
|
|
244
|
-
if(!callback) callback = function(){};
|
|
245
|
-
if(credentials.token) {
|
|
246
|
-
return Token.login(credentials, callback);
|
|
247
|
-
} else {
|
|
248
|
-
|
|
249
|
-
var q = {};
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
authFields.forEach(function(fieldName) {
|
|
253
|
-
q[fieldName] = fieldName == "password" ? hashPass(String(credentials.password)) : credentials[fieldName];
|
|
254
|
-
if(fieldName == "email") q[fieldName] = String(credentials[fieldName]).toLowerCase();
|
|
255
|
-
});
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
this.findOne(q, outcome.error(callback).success(function(account) {
|
|
259
|
-
if(!account) return callback(new comerr.IncorrectInput("Incorrect email / password"));
|
|
260
|
-
callback(null, account);
|
|
261
|
-
}));
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
/**
|
|
266
|
-
*/
|
|
267
|
-
|
|
268
|
-
function hashPass(pass) {
|
|
269
|
-
return crypto.createHash("sha1").update(pass).digest("hex");
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
*/
|
|
274
|
-
|
|
275
|
-
function randomPass() {
|
|
276
|
-
return hashPass(Date.now() + "_" + Math.round(Math.random() * 99999))
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
return database.model("accounts", Account);
|
|
280
|
-
}
|
|
281
|
-
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
exports.model = function(con) {
|
|
2
|
-
var Schema = con.base.Schema,
|
|
3
|
-
ObjectId = Schema.Types.ObjectId;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
var LostPasswordSchema = new Schema({
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
"createdAt": { type: Date, default: Date.now },
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* 10 minutes
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
"expiresAt": { type: Date, default: Date.now() + 1000 * 60 * 60 },
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* account this associated with
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
|
-
"account": ObjectId
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return con.model("lostPassword", LostPasswordSchema);
|
|
28
|
-
}
|
package/lib/models/token.js
DELETED
|
@@ -1,298 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* tokens are especially useful when turning on / off features
|
|
4
|
-
* of an account. They're used for items such as bookmarklets, and perhaps
|
|
5
|
-
* public tokens which modifies the user's account.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
var step = require("step"),
|
|
9
|
-
outcome = require("outcome"),
|
|
10
|
-
access = require("../access"),
|
|
11
|
-
_ = require("underscore"),
|
|
12
|
-
dsync = require("dsync"),
|
|
13
|
-
comerr = require("comerr");
|
|
14
|
-
|
|
15
|
-
exports.model = function(database) {
|
|
16
|
-
|
|
17
|
-
var Schema = database.base.Schema,
|
|
18
|
-
ObjectId = Schema.Types.ObjectId;
|
|
19
|
-
|
|
20
|
-
var Scope = new Schema({
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* the specific
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
item: ObjectId,
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* col - collection is reserved
|
|
30
|
-
*/
|
|
31
|
-
|
|
32
|
-
collectionName: String,
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* access level, read, write, read+write
|
|
36
|
-
*/
|
|
37
|
-
|
|
38
|
-
access: [String]
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
var Token = new Schema({
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* granter of this token
|
|
45
|
-
*/
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
account: { type: ObjectId, required: true },
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
*/
|
|
52
|
-
|
|
53
|
-
createdAt: { type: Date, default: Date.now },
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* public key used to login. This can be refreshed.
|
|
57
|
-
*/
|
|
58
|
-
|
|
59
|
-
key: { type: String, default: generateKey },
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* when does the token expire?
|
|
63
|
-
*/
|
|
64
|
-
|
|
65
|
-
expiresAt: Date,
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
*/
|
|
69
|
-
|
|
70
|
-
scopes: { type: [ Scope ], select: false },
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* time in seconds to keep token alive for. -1 = forever
|
|
74
|
-
*/
|
|
75
|
-
|
|
76
|
-
ttl: { type: Number, default: -1, select: false },
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
*/
|
|
80
|
-
|
|
81
|
-
main: { type: Boolean, select: false }
|
|
82
|
-
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
Token.publicKeys = ["account", "createdAt", "expiresAt", "key"];
|
|
86
|
-
Token.plugin(dsync.schema);
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
*/
|
|
90
|
-
|
|
91
|
-
Token.statics.getMainToken = function(account, callback) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
var self = this, Token = this, on = outcome.error(callback);
|
|
95
|
-
step(
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
*/
|
|
99
|
-
|
|
100
|
-
function() {
|
|
101
|
-
self.findOne({ account: account._id, main: true }, this);
|
|
102
|
-
},
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
*/
|
|
106
|
-
|
|
107
|
-
on.success(function(token) {
|
|
108
|
-
var next = this;
|
|
109
|
-
if(!token) {
|
|
110
|
-
token = new Token({
|
|
111
|
-
main: true,
|
|
112
|
-
account: account._id,
|
|
113
|
-
scopes:[{
|
|
114
|
-
collectionName: null, //ALL
|
|
115
|
-
item: null, //ALL
|
|
116
|
-
access: access.all(true)
|
|
117
|
-
}]
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
return token.save(function() {
|
|
121
|
-
next(null, token);
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
account.token = token;
|
|
125
|
-
next(null, token);
|
|
126
|
-
}),
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
*/
|
|
130
|
-
|
|
131
|
-
callback
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* login with a token
|
|
137
|
-
*/
|
|
138
|
-
|
|
139
|
-
Token.statics.login = function(options, callback) {
|
|
140
|
-
var token = options.token,
|
|
141
|
-
Account = this.model("accounts"),
|
|
142
|
-
Token = this,
|
|
143
|
-
on = outcome.error(callback);
|
|
144
|
-
|
|
145
|
-
var t, a;
|
|
146
|
-
|
|
147
|
-
step(
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
*/
|
|
151
|
-
|
|
152
|
-
function() {
|
|
153
|
-
Token.findOne({ key: token }, this);
|
|
154
|
-
},
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
*/
|
|
158
|
-
|
|
159
|
-
on.success(function(token) {
|
|
160
|
-
|
|
161
|
-
//404
|
|
162
|
-
if(!token) return callback(new comerr.NotFound("token does not exist", { type: "token" }));
|
|
163
|
-
|
|
164
|
-
//expired - TODO - add in query: {$or:[{expiresAt:null},{expiresAt:{$lt:new Date()}}]}
|
|
165
|
-
if(token.expiresAt && token.expiresAt.getTime() < Date.now().getTime()) {
|
|
166
|
-
token.remove();
|
|
167
|
-
return callback(new comerr.Expired("token has expired"));
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
//find the user
|
|
171
|
-
t = token;
|
|
172
|
-
Account.findOne({ _id: token.account }, this);
|
|
173
|
-
}),
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
*/
|
|
177
|
-
|
|
178
|
-
on.success(function(account) {
|
|
179
|
-
|
|
180
|
-
//this shouldn't happen
|
|
181
|
-
if(!account) return callback(new comerr.NotFound("account does not exist", { type: "account" }));
|
|
182
|
-
|
|
183
|
-
a = account;
|
|
184
|
-
//attach the token so the account can restrict some access to features
|
|
185
|
-
account.token = t;
|
|
186
|
-
|
|
187
|
-
this(null, account);
|
|
188
|
-
}),
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
*/
|
|
192
|
-
|
|
193
|
-
callback
|
|
194
|
-
);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
*/
|
|
199
|
-
|
|
200
|
-
Token.statics.createToken = function(account, options, callback) {
|
|
201
|
-
|
|
202
|
-
if(arguments.length === 2) {
|
|
203
|
-
callback = options;
|
|
204
|
-
options = {};
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
var item, collectionName, acc = options.access || access.all(false);
|
|
208
|
-
|
|
209
|
-
if(options.item) {
|
|
210
|
-
if(options.item._id) {
|
|
211
|
-
item = options.item._id;
|
|
212
|
-
collectionName = options.item.collection.name;
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
var self = this, Token = this, on = outcome.error(callback);
|
|
217
|
-
step(
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
*/
|
|
221
|
-
|
|
222
|
-
function() {
|
|
223
|
-
token = new Token({
|
|
224
|
-
account: account._id,
|
|
225
|
-
ttl: options.ttl || -1,
|
|
226
|
-
scopes: [{
|
|
227
|
-
item: item,
|
|
228
|
-
collectionName: collectionName,
|
|
229
|
-
access: acc
|
|
230
|
-
}]
|
|
231
|
-
});
|
|
232
|
-
account.token = token;
|
|
233
|
-
token.save(this);
|
|
234
|
-
},
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
*/
|
|
238
|
-
|
|
239
|
-
callback
|
|
240
|
-
)
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
/**
|
|
244
|
-
*/
|
|
245
|
-
|
|
246
|
-
Token.methods.authorized = function(item, acc) {
|
|
247
|
-
|
|
248
|
-
if(!acc) acc = [access.SUPER];
|
|
249
|
-
|
|
250
|
-
var collectionName = item.collection.name,
|
|
251
|
-
itemId = String(item._id),
|
|
252
|
-
acc2 = acc instanceof Array ? acc : [acc];
|
|
253
|
-
|
|
254
|
-
return !!_.find(item.scopes, function(scope) {
|
|
255
|
-
|
|
256
|
-
//no collection (all), OR the collection matches
|
|
257
|
-
return (!!scope.collectionName || (scope.collectionName === collectionName)) &&
|
|
258
|
-
|
|
259
|
-
//AND no item, OR the item matches the scoped item
|
|
260
|
-
(!!scope.item || (String(scope.item) === itemId)) &&
|
|
261
|
-
|
|
262
|
-
//AND the scope access intersects. This must intersect.
|
|
263
|
-
!!_intersection(scope.access, acc2).length;
|
|
264
|
-
})
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
/**
|
|
268
|
-
* regenerates the key used to login
|
|
269
|
-
*/
|
|
270
|
-
|
|
271
|
-
Token.methods.regenerateKey = function() {
|
|
272
|
-
this.key = generateKey();
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
/**
|
|
276
|
-
* make sure the grantee is set
|
|
277
|
-
*/
|
|
278
|
-
|
|
279
|
-
Token.pre("save", function(next) {
|
|
280
|
-
if(~this.ttl && !this.expiresAt) {
|
|
281
|
-
this.expiresAt = Date.now() + this.ttl;
|
|
282
|
-
}
|
|
283
|
-
next();
|
|
284
|
-
});
|
|
285
|
-
|
|
286
|
-
/**
|
|
287
|
-
*/
|
|
288
|
-
|
|
289
|
-
function generateKey() {
|
|
290
|
-
return Date.now() + "_" + Math.round(Math.random() * 999999999999999);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
/**
|
|
294
|
-
*/
|
|
295
|
-
|
|
296
|
-
return database.model("tokens", Token);
|
|
297
|
-
}
|
|
298
|
-
|