@cocreate/authorize 1.13.3 → 1.14.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 CHANGED
@@ -1,3 +1,10 @@
1
+ # [1.14.0](https://github.com/CoCreate-app/CoCreate-authorize/compare/v1.13.3...v1.14.0) (2024-05-08)
2
+
3
+
4
+ ### Features
5
+
6
+ * **permissions:** Add new operators '$storage', '$database', '$array', '$index' ([cdbc51f](https://github.com/CoCreate-app/CoCreate-authorize/commit/cdbc51f095b93df079f73f837fad21870f13882c))
7
+
1
8
  ## [1.13.3](https://github.com/CoCreate-app/CoCreate-authorize/compare/v1.13.2...v1.13.3) (2024-02-05)
2
9
 
3
10
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cocreate/authorize",
3
- "version": "1.13.3",
3
+ "version": "1.14.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",
package/src/index.js CHANGED
@@ -165,7 +165,7 @@
165
165
 
166
166
  let status = await checkMethod(data, authorized.actions, data.method)
167
167
 
168
- // console.log(data.method, status)
168
+ // console.log(data.method, data.array, status)
169
169
 
170
170
  if (!status) {
171
171
  return false
@@ -217,50 +217,117 @@
217
217
  status = await checkMethodMatch(data, authorized[i], newmatch)
218
218
  }
219
219
  } else if (typeof authorized === 'object') {
220
- let keys = Object.keys(authorized);
221
-
222
- for (const key of keys) {
223
- if (key.includes('$'))
224
- status = await checkMethodOperators(data, key, authorized[key])
225
- else if (newmatch && (authorized[newmatch] || authorized['*'])) {
226
- status = await checkMethodMatch(data, authorized[newmatch] || authorized['*'], newmatch)
220
+ for (const key of Object.keys(authorized)) {
221
+ if (key.includes('$')) {
222
+ if (['$storage', '$database', '$array', '$index'].includes(key)) {
223
+ let opStatus = await checkMethodOperators(data, key, authorized[key])
224
+ if (opStatus === true || opStatus === false)
225
+ status = opStatus
226
+ } else {
227
+ let isFilter = applyFilter(data, authorized[key], key)
228
+ console.log('isFIlter', isFilter)
229
+ }
227
230
  }
228
231
  }
229
232
  }
233
+ if (newmatch) {
234
+ if (!status && authorized[newmatch]) {
235
+ status = await checkMethodMatch(data, authorized[newmatch], newmatch)
236
+ }
237
+ if (!status && authorized['*']) {
238
+ status = await checkMethodMatch(data, authorized['*'], newmatch)
239
+ }
240
+ }
241
+
230
242
  return status
231
243
  }
232
244
  }
233
245
 
234
- async function checkMethodOperators(data, key, value) {
235
- if (value === '$user_Id' && data.socket)
236
- value = data.socket.user_id || data.user_id
246
+ async function checkMethodOperators(data, key, authorization) {
247
+ try {
248
+ // Adjust authorization if it's based on a dynamic user ID from sockets
249
+ if (authorization === '$user_id' && data.socket) {
250
+ authorization = data.socket.user_id || data.user_id;
251
+ }
237
252
 
238
- // TODO: support our standard query system
239
- let keys = key.split('.')
240
- 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])) {
253
+ if (key.startsWith('$')) {
254
+ let type = key.substring(1);
255
+
256
+ if (!data[type]) {
257
+ return undefined;
258
+ }
259
+
260
+ if (typeof data[type] === 'string') {
261
+ return checkAuthorizationData(data, authorization, data[type])
262
+ } else if (Array.isArray(data[type])) {
263
+ if (!data[type].length)
264
+ return undefined
265
+ // ToDo: Current stratergy checks if all items match else false will be returned
266
+ let allAuthorized = true;
267
+ for (let i = 0; i < data[type].length; i++) {
268
+ const itemData = typeof data[type][i] === 'object' ? data[type][i].name : data[type][i];
269
+ const authResult = checkAuthorizationData(data, authorization, itemData);
270
+ if (authResult === false) {
271
+ return false; // Return false as soon as one item is unauthorized
272
+ } else if (authResult === undefined) {
273
+ allAuthorized = undefined
274
+ }
275
+ }
276
+ return allAuthorized;
277
+ } else if (typeof data[type] === 'object') {
278
+ return checkAuthorizationData(data, authorization, data[type].name)
279
+ }
280
+ }
281
+ return undefined;
282
+ } catch (e) {
283
+ console.log(e);
284
+ return undefined;
285
+ }
286
+ }
287
+
288
+ function checkAuthorizationData(data, authorization, key) {
289
+ if (typeof authorization === 'string') {
290
+ if (key === authorization)
291
+ return true
292
+ else
293
+ return undefined
294
+ } else if (Array.isArray(authorization)) {
295
+ if (authorization.includes(key))
296
+ return true
297
+ else
298
+ return undefined
299
+ } else if (typeof authorization === 'object') {
300
+ if (typeof authorization[key] === 'object') {
301
+ for (const queryKey of Object.keys(authorization[key])) {
302
+ return applyFilter(data, authorization[key], queryKey)
303
+ }
304
+ } else if (authorization[key] === false || authorization[key] === 'false')
305
+ return false
306
+ else if (authorization[key])
307
+ return true
308
+ else
309
+ return undefined
310
+ }
311
+ }
312
+
313
+ function applyFilter(data, authorization, authorizationKey) {
314
+ let keyParts = authorizationKey.split('.');
315
+ let operator = keyParts.pop();
316
+ let key = keyParts.join('.');
317
+ if (['$eq', '$ne', '$lt', '$lte', '$gt', '$gte', '$in', '$nin', '$or', '$and', '$not', '$nor', '$exists', '$type', '$mod', '$regex', '$text', '$where', '$all', '$elemMatch', '$size'].includes(operator)) {
241
318
  if (!data.$filter)
242
319
  data.$filter = { query: {} }
243
320
  else if (!data.$filter.query)
244
321
  data.$filter.query = {}
245
322
 
246
- data.$filter.query[keys[1]] = { [keys[0]]: value }
323
+ if (authorization[authorizationKey] === '$user_id' && data.socket) {
324
+ authorization[authorizationKey] = data.socket.user_id || data.user_id;
325
+ }
247
326
 
248
- } else {
249
- if (key === '$array' && value === 'questions') {
250
- if (typeof data.array === 'string') {
251
- if (typeof value === 'string') {
252
- return data.array === value
253
- } else if (Array.isArray(value)) {
254
- return value.includes(data.array)
255
- }
256
- } else if (Array.isArray(data.array)) {
327
+ data.$filter.query[key] = { [operator]: authorization[authorizationKey] }
257
328
 
258
- }
259
- }
260
- // TODO: sanitize data by removing items user does not have access to.
261
- // console.log('key is a query operator', key)
329
+ return true
262
330
  }
263
- return true
264
331
  }
265
332
 
266
333
  async function checkFilter(authorized, data, apikey, unauthorize) {
@@ -287,7 +354,6 @@
287
354
  }
288
355
  }
289
356
 
290
-
291
357
  function deleteKey(data, path) {
292
358
  if (!data || !path) return
293
359
  if (path.includes('._id'))