@cocreate/authorize 1.7.5 → 1.8.0
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/CHANGELOG.md +24 -0
- package/package.json +3 -3
- package/src/index.js +102 -186
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,27 @@
|
|
|
1
|
+
# [1.8.0](https://github.com/CoCreate-app/CoCreate-authorize/compare/v1.7.6...v1.8.0) (2023-11-03)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* if organization_id does not exist error ([5dbdd8f](https://github.com/CoCreate-app/CoCreate-authorize/commit/5dbdd8f285418618575efc8a1e525dbde6ea81a1))
|
|
7
|
+
* improve authorization promise handling ([df00618](https://github.com/CoCreate-app/CoCreate-authorize/commit/df00618c03c129b20abb5878f73d6522dbec5401))
|
|
8
|
+
* Improve conditions ([689e6fa](https://github.com/CoCreate-app/CoCreate-authorize/commit/689e6fa95d8378f2d7bed22c1e2a2f29bc5c7be0))
|
|
9
|
+
* request.request param removed ([06a656d](https://github.com/CoCreate-app/CoCreate-authorize/commit/06a656d8b2a354ff473e8de1cfa5b44abc81bd89))
|
|
10
|
+
* update dependencies to the lates versions ([0a19463](https://github.com/CoCreate-app/CoCreate-authorize/commit/0a1946353c787a5dee1f54324e1fb2290c4b7a0f))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* check if authoriztion keys has a query operator and apply query ([e2dfa5c](https://github.com/CoCreate-app/CoCreate-authorize/commit/e2dfa5c02bbb537454e2f5d9a9b07444dd60c3a6))
|
|
16
|
+
* support adding querires for crud methods ([9b68d24](https://github.com/CoCreate-app/CoCreate-authorize/commit/9b68d244982fe08f680043cd7f1a1b06cc6be301))
|
|
17
|
+
|
|
18
|
+
## [1.7.6](https://github.com/CoCreate-app/CoCreate-authorize/compare/v1.7.5...v1.7.6) (2023-10-26)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Bug Fixes
|
|
22
|
+
|
|
23
|
+
* await key to resolve, update filters ([f69bdb7](https://github.com/CoCreate-app/CoCreate-authorize/commit/f69bdb72fe8c4b7ce8a2993699c8611442373e12))
|
|
24
|
+
|
|
1
25
|
## [1.7.5](https://github.com/CoCreate-app/CoCreate-authorize/compare/v1.7.4...v1.7.5) (2023-10-25)
|
|
2
26
|
|
|
3
27
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cocreate/authorize",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "A simple authorize component in vanilla javascript. Easily configured using HTML5 data-attributes and/or JavaScript API.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"authorize",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
},
|
|
46
46
|
"main": "./src/index.js",
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@cocreate/crud-client": "^1.28.
|
|
49
|
-
"@cocreate/utils": "^1.26.
|
|
48
|
+
"@cocreate/crud-client": "^1.28.12",
|
|
49
|
+
"@cocreate/utils": "^1.26.2"
|
|
50
50
|
}
|
|
51
51
|
}
|
package/src/index.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
}
|
|
16
16
|
}(typeof self !== 'undefined' ? self : this, function (isBrowser, crud, { getValueFromObject, dotNotationToObject }) {
|
|
17
17
|
|
|
18
|
-
const
|
|
18
|
+
const organizations = {}
|
|
19
19
|
|
|
20
20
|
if (isBrowser) {
|
|
21
21
|
crud.listen('update.object', function (data) {
|
|
@@ -36,9 +36,9 @@
|
|
|
36
36
|
|
|
37
37
|
if (array === 'keys' && object) {
|
|
38
38
|
let authorization = object[0]
|
|
39
|
-
if (authorization && authorization.key &&
|
|
39
|
+
if (authorization && authorization.key && organizations[organization_id] && organizations[organization_id][authorization.key]) {
|
|
40
40
|
let newAuthorization = await readAuthorization(authorization.key, organization_id)
|
|
41
|
-
|
|
41
|
+
organizations[organization_id][authorization.key] = newAuthorization
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
}
|
|
@@ -48,44 +48,21 @@
|
|
|
48
48
|
|
|
49
49
|
if (array === 'keys' && object) {
|
|
50
50
|
let authorization = object[0]
|
|
51
|
-
if (authorization && authorization.key &&
|
|
52
|
-
|
|
51
|
+
if (authorization && authorization.key && organizations[organization_id] && organizations[organization_id][authorization.key]) {
|
|
52
|
+
delete organizations[organization_id][authorization.key]
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
function setAuthorization(key, authorization) {
|
|
58
|
-
authorizations.set(key, authorization)
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function hasAuthorization(key) {
|
|
62
|
-
return authorizations.has(key)
|
|
63
|
-
}
|
|
64
|
-
|
|
65
57
|
async function getAuthorization(key, organization_id) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
// Return the value or pending promise
|
|
69
|
-
return authorizations.get(key);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Create a new promise and store it
|
|
73
|
-
const authorizationPromise = readAuthorization(key, organization_id);
|
|
74
|
-
authorizations.set(key, authorizationPromise);
|
|
75
|
-
|
|
76
|
-
try {
|
|
77
|
-
// Wait for the authorization to be resolved
|
|
78
|
-
const authorization = await authorizationPromise;
|
|
58
|
+
if (!organizations[organization_id])
|
|
59
|
+
organizations[organization_id] = {}
|
|
79
60
|
|
|
80
|
-
|
|
81
|
-
|
|
61
|
+
if (!organizations[organization_id][key])
|
|
62
|
+
organizations[organization_id][key] = readAuthorization(key, organization_id);
|
|
82
63
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
// Handle errors if necessary
|
|
86
|
-
authorizations.delete(key);
|
|
87
|
-
throw error;
|
|
88
|
-
}
|
|
64
|
+
organizations[organization_id][key] = await organizations[organization_id][key]
|
|
65
|
+
return organizations[organization_id][key]
|
|
89
66
|
}
|
|
90
67
|
|
|
91
68
|
async function readAuthorization(key, organization_id) {
|
|
@@ -94,20 +71,19 @@
|
|
|
94
71
|
return { error: 'An organization_id is required' };
|
|
95
72
|
|
|
96
73
|
let request = {
|
|
97
|
-
method: 'read
|
|
74
|
+
method: 'object.read',
|
|
75
|
+
database: organization_id,
|
|
98
76
|
array: 'keys',
|
|
99
77
|
organization_id,
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
query: []
|
|
103
|
-
}
|
|
78
|
+
$filter: {
|
|
79
|
+
query: []
|
|
104
80
|
}
|
|
105
81
|
}
|
|
106
82
|
|
|
107
83
|
if (key)
|
|
108
|
-
request
|
|
84
|
+
request.$filter.query.push({ key: 'key', value: key, operator: '$eq' })
|
|
109
85
|
else
|
|
110
|
-
request
|
|
86
|
+
request.$filter.query.push({ key: 'default', value: true, operator: '$eq' })
|
|
111
87
|
|
|
112
88
|
|
|
113
89
|
let authorization = await crud.send(request)
|
|
@@ -125,20 +101,19 @@
|
|
|
125
101
|
role_ids.push({ _id })
|
|
126
102
|
})
|
|
127
103
|
|
|
128
|
-
delete request
|
|
129
|
-
delete request.
|
|
104
|
+
delete request.$filter
|
|
105
|
+
delete request.isFilter
|
|
106
|
+
|
|
130
107
|
request.object = role_ids
|
|
131
108
|
|
|
132
109
|
let roles = await crud.send(request)
|
|
133
110
|
roles = roles.object
|
|
134
111
|
|
|
135
|
-
authorization = createAuthorization(authorization, roles)
|
|
112
|
+
authorization = await createAuthorization(authorization, roles)
|
|
136
113
|
}
|
|
137
|
-
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
return authorization;
|
|
141
|
-
|
|
114
|
+
return authorization;
|
|
115
|
+
} else
|
|
116
|
+
return {}
|
|
142
117
|
} catch (error) {
|
|
143
118
|
console.log("authorization Error", error)
|
|
144
119
|
return { error };
|
|
@@ -199,171 +174,111 @@
|
|
|
199
174
|
}
|
|
200
175
|
|
|
201
176
|
async function checkAuthorization({ key, data }) {
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
if (!
|
|
205
|
-
return { error: '' };
|
|
177
|
+
if (!data.organization_id)
|
|
178
|
+
return { error: 'organization_id is required' };
|
|
179
|
+
if (!data.method)
|
|
180
|
+
return { error: 'method is required' };
|
|
206
181
|
|
|
207
|
-
let authorized = await getAuthorization(key, organization_id)
|
|
182
|
+
let authorized = await getAuthorization(key, data.organization_id)
|
|
208
183
|
if (!authorized || authorized.error)
|
|
209
184
|
return authorized
|
|
210
|
-
if (authorized.organization_id !== organization_id)
|
|
185
|
+
if (authorized.organization_id !== data.organization_id)
|
|
211
186
|
return false;
|
|
212
187
|
if (authorized.host && authorized.host.length) {
|
|
213
188
|
if (!authorized.host || (!authorized.host.includes(data.host) && !authorized.host.includes("*")))
|
|
214
189
|
return false;
|
|
215
|
-
|
|
216
190
|
}
|
|
217
|
-
if (authorized.admin
|
|
191
|
+
if (authorized.admin === 'true' || authorized.admin === true)
|
|
218
192
|
return true;
|
|
219
193
|
|
|
220
|
-
let status = await checkMethod(authorized.actions, method
|
|
194
|
+
let status = await checkMethod(data, authorized.actions, data.method)
|
|
195
|
+
|
|
196
|
+
// console.log(data.method, status)
|
|
221
197
|
|
|
222
|
-
if (!status)
|
|
198
|
+
if (!status) {
|
|
223
199
|
return false
|
|
200
|
+
}
|
|
224
201
|
|
|
225
202
|
return { authorized: data };
|
|
226
203
|
}
|
|
227
204
|
|
|
228
|
-
async function checkMethod(
|
|
229
|
-
if (
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
let
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
if (
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
}
|
|
244
|
-
return true
|
|
205
|
+
async function checkMethod(data, authorized, method) {
|
|
206
|
+
if (authorized[method]) {
|
|
207
|
+
return await checkMethodMatch(data, authorized[method], method)
|
|
208
|
+
} else if (method.includes('.')) {
|
|
209
|
+
let match = ''
|
|
210
|
+
let splitMethod = method.split('.')
|
|
211
|
+
for (let i = 0; i < splitMethod.length; i++) {
|
|
212
|
+
if (!match)
|
|
213
|
+
match = splitMethod[i]
|
|
214
|
+
else
|
|
215
|
+
match += '.' + splitMethod[i]
|
|
216
|
+
if (authorized[match]) {
|
|
217
|
+
return await checkMethodMatch(data, authorized[match], match)
|
|
218
|
+
} else if (i === splitMethod.length - 1)
|
|
219
|
+
return false
|
|
245
220
|
}
|
|
246
221
|
} else
|
|
247
|
-
return false
|
|
222
|
+
return false;
|
|
248
223
|
}
|
|
249
224
|
|
|
250
|
-
async function
|
|
251
|
-
if (
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
if (authorized[i] === true)
|
|
225
|
+
async function checkMethodMatch(data, authorized, match) {
|
|
226
|
+
if (typeof authorized === 'boolean') {
|
|
227
|
+
return authorized
|
|
228
|
+
} else if (typeof authorized === 'string') {
|
|
229
|
+
if (authorized === 'false')
|
|
230
|
+
return false
|
|
231
|
+
else if (authorized === 'true')
|
|
258
232
|
return true
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
233
|
+
else if (authorized === match)
|
|
234
|
+
return true // check string for match or mutate data
|
|
235
|
+
else
|
|
236
|
+
return true // check string for match or mutate data
|
|
237
|
+
} else if (typeof authorized === 'number') {
|
|
238
|
+
return !!authorized
|
|
239
|
+
} else {
|
|
240
|
+
let status = false
|
|
241
|
+
let newmatch = data.method.replace(match, '')
|
|
242
|
+
|
|
243
|
+
if (Array.isArray(authorized)) {
|
|
244
|
+
for (let i = 0; i < authorized.length; i++) {
|
|
245
|
+
status = await checkMethodMatch(data, authorized[i], newmatch)
|
|
246
|
+
}
|
|
247
|
+
} else if (typeof authorized === 'object') {
|
|
248
|
+
let keys = Object.keys(authorized);
|
|
249
|
+
|
|
250
|
+
for (const key of keys) {
|
|
251
|
+
if (key.includes('$'))
|
|
252
|
+
status = await checkMethodOperators(data, key, authorized[key])
|
|
253
|
+
else if (newmatch && (authorized[newmatch] || authorized['*'])) {
|
|
254
|
+
status = await checkMethodMatch(data, authorized[newmatch] || authorized['*'], newmatch)
|
|
255
|
+
}
|
|
256
|
+
}
|
|
273
257
|
}
|
|
274
|
-
|
|
258
|
+
return status
|
|
275
259
|
}
|
|
276
|
-
|
|
277
|
-
return status
|
|
278
|
-
|
|
279
260
|
}
|
|
280
261
|
|
|
281
|
-
async function
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
if (
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
if (
|
|
292
|
-
|
|
293
|
-
else if (data[key]) {
|
|
294
|
-
keyStatus = await checkArray(authorized, data, key, unauthorize)
|
|
295
|
-
if (await checkFilter(authorized, data, key, unauthorize))
|
|
296
|
-
status = true
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
// if authorized[key] is an array
|
|
301
|
-
else if (Array.isArray(authorized[key])) {
|
|
302
|
-
if (authorized[key].includes(true) || authorized[key].includes('true') || authorized[key].includes('*'))
|
|
303
|
-
keyStatus = true
|
|
304
|
-
else if (data[key]) {
|
|
305
|
-
keyStatus = await checkArray(authorized, data, key, unauthorize)
|
|
306
|
-
if (await checkFilter(authorized, data, key, unauthorize))
|
|
307
|
-
status = true
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
// if authorized[key] is an object
|
|
312
|
-
else if (typeof authorized[key] === "object") {
|
|
313
|
-
console.log('authorized[key] is an object', authorized[key])
|
|
314
|
-
} else
|
|
315
|
-
delete data[key]
|
|
316
|
-
|
|
317
|
-
// if key status is false for unauthorized case
|
|
318
|
-
if (!keyStatus || keyStatus && unauthorize) {
|
|
319
|
-
if (!data.unauthorized || !data.unauthorized[method])
|
|
320
|
-
data.unauthorized = { [method]: { [key]: [data[key]] } }
|
|
321
|
-
else if (!data.unauthorized[method][key])
|
|
322
|
-
data.unauthorized[method][key] = [data[key]]
|
|
262
|
+
async function checkMethodOperators(data, key, value) {
|
|
263
|
+
if (value === 'this.userId' && data.socket)
|
|
264
|
+
value = data.socket.user_id
|
|
265
|
+
|
|
266
|
+
let keys = key.split('.')
|
|
267
|
+
if (['$eq', '$ne', '$lt', '$lte', '$gt', '$gte', '$in', '$nin', '$or', '$and', '$not', '$nor', '$exists', '$type', '$mod', '$regex', '$text', '$where', '$all', '$elemMatch', '$size'].includes(keys[0])) {
|
|
268
|
+
// let keys = key.split('.')
|
|
269
|
+
let query = { key: keys[1], value, operator: keys[0] }
|
|
270
|
+
if (!data.$filter)
|
|
271
|
+
data.$filter = { query: [query] }
|
|
272
|
+
else if (!data.$filter.query)
|
|
273
|
+
data.$filter.query = [query]
|
|
323
274
|
else
|
|
324
|
-
data.
|
|
325
|
-
} else
|
|
326
|
-
status = true
|
|
327
|
-
return status
|
|
328
|
-
}
|
|
275
|
+
data.$filter.query.push(query)
|
|
329
276
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
let dataValue = getValueFromObject(data, key);
|
|
334
|
-
|
|
335
|
-
if (!authorizedValue && !unauthorize) {
|
|
336
|
-
data = deleteKey(data, key)
|
|
337
|
-
} else if (typeof dataValue == "string") {
|
|
338
|
-
if (unauthorize && authorizedValue.includes(dataValue))
|
|
339
|
-
data = deleteKey(data, key)
|
|
340
|
-
else {
|
|
341
|
-
if (!authorizedValue.includes(dataValue))
|
|
342
|
-
data = deleteKey(data, key)
|
|
343
|
-
else
|
|
344
|
-
keyStatus = true
|
|
345
|
-
}
|
|
346
|
-
} else if (Array.isArray(dataValue)) {
|
|
347
|
-
for (let i = 0; i < dataValue.length; i++) {
|
|
348
|
-
keyStatus = await checkArray(authorized, data, `${key}[${i}]`, unauthorize)
|
|
349
|
-
}
|
|
350
|
-
} else if (typeof dataValue === "object") {
|
|
351
|
-
let checkKeys = true
|
|
352
|
-
if (dataValue['_id']) {
|
|
353
|
-
if (authorized.object.includes(dataValue['_id']))
|
|
354
|
-
checkKeys = true
|
|
355
|
-
}
|
|
356
|
-
if (checkKeys) {
|
|
357
|
-
if (authorizedValue['*'] || authorizedValue['*'] == '')
|
|
358
|
-
keyStatus = true
|
|
359
|
-
else
|
|
360
|
-
for (const k of Object.keys(dataValue)) {
|
|
361
|
-
keyStatus = await checkArray(authorized, data, `${key}.${k}`, unauthorize)
|
|
362
|
-
}
|
|
363
|
-
}
|
|
277
|
+
} else {
|
|
278
|
+
// TODO: sanitize data by removing items user does not have access to.
|
|
279
|
+
// console.log('key is a query operator', key)
|
|
364
280
|
}
|
|
365
|
-
|
|
366
|
-
return keyStatus
|
|
281
|
+
return true
|
|
367
282
|
}
|
|
368
283
|
|
|
369
284
|
async function checkFilter(authorized, data, apikey, unauthorize) {
|
|
@@ -388,6 +303,7 @@
|
|
|
388
303
|
}
|
|
389
304
|
}
|
|
390
305
|
|
|
306
|
+
|
|
391
307
|
function deleteKey(data, path) {
|
|
392
308
|
if (!data || !path) return
|
|
393
309
|
if (path.includes('._id'))
|