@researchdatabox/sails-hook-redbox-storage-mongo 1.4.9 → 1.5.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.
@@ -0,0 +1,12 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "github-actions"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
7
+ target-branch: "master"
8
+ - package-ecosystem: "npm"
9
+ directory: "/"
10
+ schedule:
11
+ interval: "weekly"
12
+ target-branch: "master"
package/README.md CHANGED
File without changes
File without changes
File without changes
File without changes
@@ -12,8 +12,9 @@ var __await = (this && this.__await) || function (v) { return this instanceof __
12
12
  var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
13
13
  if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
14
14
  var g = generator.apply(thisArg, _arguments || []), i, q = [];
15
- return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
16
- function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
15
+ return i = {}, verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;
16
+ function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }
17
+ function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }
17
18
  function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
18
19
  function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
19
20
  function fulfill(value) { resume("next", value); }
@@ -24,7 +25,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
24
25
  exports.Services = void 0;
25
26
  const Rx_1 = require("rxjs/Rx");
26
27
  const uuid_1 = require("uuid");
27
- const moment = require("moment");
28
+ const luxon_1 = require("luxon");
28
29
  const mongodb = require("mongodb");
29
30
  const util = require("util");
30
31
  const stream = require("stream");
@@ -151,8 +152,14 @@ var Services;
151
152
  response.success = true;
152
153
  }
153
154
  catch (err) {
154
- sails.log.error(`${this.logHeader} Failed to save update to MongoDB:`);
155
- sails.log.error(JSON.stringify(err));
155
+ sails.log.error(`${this.logHeader} Failed to save update to MongoDB: ${JSON.stringify({
156
+ error: err,
157
+ response: response,
158
+ brand: brand,
159
+ oid: oid,
160
+ record: record,
161
+ user: user,
162
+ })}`);
156
163
  response.success = false;
157
164
  response.message = err;
158
165
  }
@@ -199,28 +206,24 @@ var Services;
199
206
  provideUserAccessAndRemovePendingAccess(oid, userid, pendingValue) {
200
207
  const batchFn = () => __awaiter(this, void 0, void 0, function* () {
201
208
  const metadata = yield this.getMeta(oid);
202
- var pendingEditArray = metadata['authorization']['editPending'];
203
- var editArray = metadata['authorization']['edit'];
204
- for (var i = 0; i < pendingEditArray.length; i++) {
205
- if (pendingEditArray[i] == pendingValue) {
206
- pendingEditArray = pendingEditArray.filter(e => e !== pendingValue);
207
- editArray = editArray.filter(e => e !== userid);
208
- editArray.push(userid);
209
- }
210
- }
211
- metadata['authorization']['editPending'] = pendingEditArray;
212
- metadata['authorization']['edit'] = editArray;
213
- var pendingViewArray = metadata['authorization']['viewPending'];
214
- var viewArray = metadata['authorization']['view'];
215
- for (var i = 0; i < pendingViewArray.length; i++) {
216
- if (pendingViewArray[i] == pendingValue) {
217
- pendingViewArray = pendingViewArray.filter(e => e !== pendingValue);
218
- viewArray = viewArray.filter(e => e !== userid);
219
- viewArray.push(userid);
220
- }
221
- }
222
- metadata['authorization']['viewPending'] = pendingViewArray;
223
- metadata['authorization']['view'] = viewArray;
209
+ const pendingEditArray = _.get(metadata, 'authorization.editPending', []);
210
+ const editArray = _.get(metadata, 'authorization.edit', []);
211
+ const pendingEditArrayFiltered = pendingEditArray.filter(value => value !== pendingValue);
212
+ const pendingEditFound = pendingEditArray.length > pendingEditArrayFiltered.length;
213
+ if (pendingEditFound && !editArray.includes(userid)) {
214
+ editArray.push(userid);
215
+ }
216
+ _.set(metadata, 'authorization.editPending', pendingEditArrayFiltered);
217
+ _.set(metadata, 'authorization.edit', editArray);
218
+ const pendingViewArray = _.get(metadata, 'authorization.viewPending', []);
219
+ const viewArray = _.get(metadata, 'authorization.view', []);
220
+ const pendingViewArrayFiltered = pendingViewArray.filter(value => value !== pendingValue);
221
+ const pendingViewFound = pendingViewArray.length > pendingViewArrayFiltered.length;
222
+ if (pendingViewFound && !viewArray.includes(userid)) {
223
+ viewArray.push(userid);
224
+ }
225
+ _.set(metadata, 'authorization.viewPending', pendingViewArrayFiltered);
226
+ _.set(metadata, 'authorization.view', viewArray);
224
227
  try {
225
228
  yield this.updateMeta(null, oid, metadata);
226
229
  }
@@ -231,8 +234,8 @@ var Services;
231
234
  });
232
235
  batchFn();
233
236
  }
234
- getRelatedRecords(oid, brand, recordTypeName = null, mappingContext = null) {
235
- return __awaiter(this, void 0, void 0, function* () {
237
+ getRelatedRecords(oid_1, brand_1) {
238
+ return __awaiter(this, arguments, void 0, function* (oid, brand, recordTypeName = null, mappingContext = null) {
236
239
  let record = yield this.getMeta(oid);
237
240
  if (_.isEmpty(recordTypeName)) {
238
241
  recordTypeName = record['metaMetadata']['type'];
@@ -284,8 +287,8 @@ var Services;
284
287
  return mappingContext;
285
288
  });
286
289
  }
287
- delete(oid, permanentlyDelete = false) {
288
- return __awaiter(this, void 0, void 0, function* () {
290
+ delete(oid_1) {
291
+ return __awaiter(this, arguments, void 0, function* (oid, permanentlyDelete = false) {
289
292
  const response = new redbox_core_types_1.StorageServiceResponse();
290
293
  try {
291
294
  if (permanentlyDelete) {
@@ -333,7 +336,7 @@ var Services;
333
336
  const logName = _.get(options, 'logName', null);
334
337
  if (logName) {
335
338
  let log = _.get(record, logName, null);
336
- const entry = { date: moment().format('YYYY-MM-DDTHH:mm:ss') };
339
+ const entry = { date: luxon_1.DateTime.now().toFormat("yyyy-LL-dd'T'HH:mm:ss") };
337
340
  if (log) {
338
341
  log.push(entry);
339
342
  }
@@ -367,8 +370,8 @@ var Services;
367
370
  return record;
368
371
  });
369
372
  }
370
- getDeletedRecords(workflowState, recordType = undefined, start, rows = 10, username, roles, brand, editAccessOnly = undefined, packageType = undefined, sort = undefined, filterFields = undefined, filterString = undefined, filterMode = 'regex') {
371
- return __awaiter(this, void 0, void 0, function* () {
373
+ getDeletedRecords(workflowState_1) {
374
+ return __awaiter(this, arguments, void 0, function* (workflowState, recordType = undefined, start, rows = 10, username, roles, brand, editAccessOnly = undefined, packageType = undefined, sort = undefined, filterFields = undefined, filterString = undefined, filterMode = 'regex') {
372
375
  let query = {
373
376
  "deletedRecordMetadata.metaMetadata.brandId": brand.id
374
377
  };
@@ -446,8 +449,8 @@ var Services;
446
449
  return response;
447
450
  });
448
451
  }
449
- getRecords(workflowState, recordType = undefined, start, rows = 10, username, roles, brand, editAccessOnly = undefined, packageType = undefined, sort = undefined, filterFields = undefined, filterString = undefined, filterMode = undefined, secondarySort = undefined) {
450
- return __awaiter(this, void 0, void 0, function* () {
452
+ getRecords(workflowState_1) {
453
+ return __awaiter(this, arguments, void 0, function* (workflowState, recordType = undefined, start, rows = 10, username, roles, brand, editAccessOnly = undefined, packageType = undefined, sort = undefined, filterFields = undefined, filterString = undefined, filterMode = undefined, secondarySort = undefined) {
451
454
  if (_.isUndefined(filterMode) || _.isNull(filterMode) || _.isEmpty(filterMode)) {
452
455
  filterMode = 'regex';
453
456
  }
@@ -563,8 +566,8 @@ var Services;
563
566
  return { items: yield this.deletedRecordCol.find(query, options).toArray(), totalItems: yield this.deletedRecordCol.count(query) };
564
567
  });
565
568
  }
566
- fetchAllRecords(query, options, stringifyJSON = false) {
567
- return __asyncGenerator(this, arguments, function* fetchAllRecords_1() {
569
+ fetchAllRecords(query_1, options_1) {
570
+ return __asyncGenerator(this, arguments, function* fetchAllRecords_1(query, options, stringifyJSON = false) {
568
571
  let skip = 0;
569
572
  let limit = options.limit;
570
573
  options.skip = skip;
package/config/record.js CHANGED
File without changes
package/config/storage.js CHANGED
File without changes
package/index.js CHANGED
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@researchdatabox/sails-hook-redbox-storage-mongo",
3
- "version": "1.4.9",
3
+ "version": "1.5.0",
4
4
  "description": "A MongoDB storage plugin for ReDBox.",
5
5
  "main": "index.js",
6
6
  "sails": {
@@ -11,9 +11,16 @@
11
11
  "url": "https://github.com/redbox-mint/sails-hook-redbox-storage-mongo.git"
12
12
  },
13
13
  "scripts": {
14
- "test": "NODE_ENV=test; mocha",
15
- "installHook": "docker run -v $(pwd):/opt/sailshook qcifengineering/redbox-portal /bin/bash -c 'cd /opt/redbox-portal;yarn add \"file:/opt/sailshook\"'; docker commit $(docker ps -lq) redboxportalwithhook",
16
- "runDev": "docker-compose -f support/development/docker-compose.yml up"
14
+ "compile": "./node_modules/typescript/bin/tsc -p tsconfig.json",
15
+ "dev:run": "docker compose -f ./support/docker-compose.yml -f ./support/docker-compose.dev.yml up --menu=false --remove-orphans --abort-on-container-exit --exit-code-from rbportal",
16
+ "predev:run": "npm install --ignore-scripts && npm run compile",
17
+ "dev:clean": "docker compose -f ./support/docker-compose.yml -f ./support/docker-compose.dev.yml down",
18
+ "dev:logs": "docker compose -f ./support/docker-compose.yml -f ./support/docker-compose.dev.yml logs",
19
+ "dev:removedata": "docker compose -f ./support/docker-compose.yml -f ./support/docker-compose.dev.yml down -v",
20
+ "test": "docker compose -f ./support/docker-compose.yml -f ./support/docker-compose.mocha.yml up --menu=false --abort-on-container-exit --exit-code-from rbportal",
21
+ "pretest": "npm install --ignore-scripts && npm run compile",
22
+ "posttest": "npm run test:clean",
23
+ "test:clean": "docker compose -f ./support/docker-compose.yml -f ./support/docker-compose.mocha.yml down -v"
17
24
  },
18
25
  "keywords": [
19
26
  "sails",
@@ -26,27 +33,32 @@
26
33
  "author": "QCIF Engineering dev@redboxresearchdata.com.au",
27
34
  "license": "GPL-3.0",
28
35
  "devDependencies": {
29
- "@researchdatabox/redbox-core-types": "^1.4.3",
30
- "@types/chai": "^4.2.12",
31
- "@types/lodash": "^4.14.159",
32
- "@types/mocha": "^8.0.3",
33
- "chai": "^4.2.0",
36
+ "@researchdatabox/redbox-core-types": "1.4.8",
37
+ "@types/chai": "5.2.2",
38
+ "@types/lodash": "4.17.17",
39
+ "@types/mocha": "10.0.10",
40
+ "@types/node": "20.17.51",
41
+ "chai": "5.2.0",
34
42
  "fs": "0.0.1-security",
35
- "mocha": "^8.1.1",
36
- "moment": "^2.29.1",
37
- "mongodb": "^6.2.0",
38
- "rxjs": "^6.6.2",
39
- "rxjs-compat": "^6.6.7",
40
- "sails": "^1.2.5",
41
- "stream": "0.0.2",
42
- "typescript": "^5.2.2",
43
- "util": "^0.12.4"
43
+ "mocha": "11.5.0",
44
+ "mocha-junit-reporter": "2.2.1",
45
+ "luxon": "^3.7.1",
46
+ "mongodb": "6.16.0",
47
+ "rxjs": "6.6.7",
48
+ "rxjs-compat": "6.6.7",
49
+ "sails": "1.5.14",
50
+ "stream": "0.0.3",
51
+ "typescript": "5.5.4",
52
+ "util": "0.12.5"
44
53
  },
45
54
  "dependencies": {
46
55
  "json2csv": "^5.0.3",
47
56
  "lodash": "^4.17.21",
48
57
  "uuid": "8.3.0"
49
58
  },
59
+ "peerDependencies": {
60
+ "luxon": ">=3.0.0"
61
+ },
50
62
  "publishConfig": {
51
63
  "access": "public"
52
64
  }
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+
3
+ module.exports = {
4
+ require: "chai",
5
+ recursive: true,
6
+ slow: 2000,
7
+ timeout: "20s",
8
+ ui: "bdd",
9
+ global: ["sails", "moment", "_", "expect"],
10
+ };
11
+
12
+ if (process.env.CI === "true") {
13
+ console.log("Mocha running in CI.");
14
+ // (For CI) Run mocha and write results to a junit format file:
15
+ module.exports["reporter"] = "mocha-junit-reporter";
16
+ module.exports["reporter-option"] = "mochaFile=/opt/redbox-portal/node_modules/@researchdatabox/sails-hook-redbox-storage-mongo/support/junit/unit-mocha.xml";
17
+ } else {
18
+ console.log("Mocha running in local dev.");
19
+ // (For development) Run mocha and show the results on stdout:
20
+ module.exports["reporter"] = "spec";
21
+ }
@@ -0,0 +1,63 @@
1
+ var sails = require("sails");
2
+ var _ = require("lodash");
3
+
4
+ global.moment = require("moment");
5
+ global.sails = sails;
6
+ global._ = _;
7
+
8
+ /* global before, after */
9
+
10
+ before(function (done) {
11
+ import("chai").then((chai) => {
12
+ global.chai = chai;
13
+ global.should = chai.should();
14
+ global.expect = chai.expect;
15
+
16
+ // Set the timeout so that Sails has enough time to lift.
17
+ this.timeout(60000);
18
+ sails.lift({
19
+ log: {
20
+ level: "verbose",
21
+ },
22
+ hooks: {
23
+ grunt: false,
24
+ },
25
+ models: {
26
+ datastore: "mongodb",
27
+ migrate: "drop",
28
+ },
29
+ datastores: {
30
+ mongodb: {
31
+ adapter: require('sails-mongo'),
32
+ url: "mongodb://mongodb:27017/redbox-portal"
33
+ },
34
+ redboxStorage: {
35
+ adapter: require('sails-mongo'),
36
+ url: 'mongodb://mongodb:27017/redbox-storage'
37
+ }
38
+ },
39
+ security: {
40
+ csrf: false,
41
+ },
42
+ auth: {
43
+ default: {
44
+ local: {
45
+ default: {
46
+ token: "auth-default-local-default-token",
47
+ },
48
+ },
49
+ },
50
+ },
51
+ }, function (err, server) {
52
+ if (err) return done(err);
53
+ done(err, sails);
54
+ });
55
+ });
56
+ });
57
+
58
+ after(function (done) {
59
+ // here you can clear fixtures, etc.
60
+ if (sails && _.isFunction(sails.lower)) {
61
+ sails.lower(done);
62
+ }
63
+ });
@@ -0,0 +1,121 @@
1
+ const service = require("../../../api/services/MongoStorageService");
2
+
3
+
4
+ /* global describe, it, expect */
5
+
6
+ async function sleep(ms = 300) {
7
+ return new Promise(resolve => setTimeout(resolve, ms));
8
+ }
9
+
10
+ describe("Records", function () {
11
+ [
12
+ {
13
+ // missing 'editPending' does not cause error
14
+ args: {
15
+ record: {
16
+ metadata: {},
17
+ "authorization": {
18
+ "viewRoles": ["Admin", "Librarians"],
19
+ "editRoles": ["Admin", "Librarians"],
20
+ "view": ["example-2@redboxresearchdata.com.au"],
21
+ "edit": [],
22
+ "viewPending": ["example-1@redboxresearchdata.com.au"]
23
+ }
24
+ }
25
+ },
26
+ expected: {
27
+ record: {
28
+ "authorization": {
29
+ "viewRoles": ["Admin", "Librarians"],
30
+ "editRoles": ["Admin", "Librarians"],
31
+ "view": ["example-2@redboxresearchdata.com.au", "example-1@redboxresearchdata.com.au"],
32
+ "edit": [],
33
+ "viewPending": [],
34
+ "editPending": [],
35
+ }
36
+ }
37
+ },
38
+ },
39
+ {
40
+ // duplicate entries in pending array are transformed to in one entry in real access array
41
+ args: {
42
+ record: {
43
+ metadata: {},
44
+ "authorization": {
45
+ "viewRoles": ["Admin", "Librarians"],
46
+ "editRoles": ["Admin", "Librarians"],
47
+ "view": ["example-2@redboxresearchdata.com.au"],
48
+ "edit": [],
49
+ "viewPending": [],
50
+ "editPending": ["example-1@redboxresearchdata.com.au", "example-1@redboxresearchdata.com.au"],
51
+ }
52
+ }
53
+ },
54
+ expected: {
55
+ record: {
56
+ "authorization": {
57
+ "viewRoles": ["Admin", "Librarians"],
58
+ "editRoles": ["Admin", "Librarians"],
59
+ "view": ["example-2@redboxresearchdata.com.au"],
60
+ "edit": ["example-1@redboxresearchdata.com.au"],
61
+ "viewPending": [],
62
+ "editPending": [],
63
+ }
64
+ }
65
+ },
66
+ },
67
+ {
68
+ // same entry in real access array and pending is removed from pending array
69
+ args: {
70
+ record: {
71
+ metadata: {},
72
+ "authorization": {
73
+ "viewRoles": ["Admin", "Librarians"],
74
+ "editRoles": ["Admin", "Librarians"],
75
+ "view": ["example-2@redboxresearchdata.com.au"],
76
+ "edit": ["example-1@redboxresearchdata.com.au"],
77
+ "viewPending": [],
78
+ "editPending": ["example-1@redboxresearchdata.com.au"],
79
+ }
80
+ }
81
+ },
82
+ expected: {
83
+ record: {
84
+ "authorization": {
85
+ "viewRoles": ["Admin", "Librarians"],
86
+ "editRoles": ["Admin", "Librarians"],
87
+ "view": ["example-2@redboxresearchdata.com.au"],
88
+ "edit": ["example-1@redboxresearchdata.com.au"],
89
+ "viewPending": [],
90
+ "editPending": [],
91
+ }
92
+ }
93
+ },
94
+ }
95
+ ].forEach(({args, expected}) => {
96
+ it(`should provideUserAccessAndRemovePendingAccess as expected '${JSON.stringify(args)}' = ${JSON.stringify(expected)}`, async function () {
97
+
98
+ const brand = 'testing-brand';
99
+ const record = args.record;
100
+ const recordType = "rdmp";
101
+
102
+ const response = await service.create(brand, record, recordType);
103
+
104
+ expect(response.oid).to.have.lengthOf(32);
105
+
106
+ const oid = response.oid;
107
+ const userid = "example-1@redboxresearchdata.com.au";
108
+ const pendingValue = "example-1@redboxresearchdata.com.au";
109
+
110
+ service.provideUserAccessAndRemovePendingAccess(oid, userid, pendingValue);
111
+ // TODO: provideUserAccessAndRemovePendingAccess is a sync method, but it calls async methods.
112
+ // So, wait for a bit for the method to complete.
113
+ // This means that any errors may not be raised, as they occur in an untracked async function.
114
+ await sleep(5000);
115
+
116
+ const result = await service.getMeta(oid);
117
+
118
+ expect(result.authorization).to.eql(expected.record.authorization);
119
+ });
120
+ });
121
+ });
@@ -1,12 +1,12 @@
1
1
  'use strict';
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const { Transform } = require('stream');
4
- const moment = require("moment");
4
+ const luxon_1 = require("luxon");
5
5
  class ExportJSONTransformer extends Transform {
6
6
  constructor(recordtype, modifiedBefore, modifiedAfter) {
7
7
  super();
8
8
  this.first = true;
9
- this.push(`{ "recordType": "${recordtype}",\n "dateGenerated": "${moment().toISOString()}",\n`);
9
+ this.push(`{ "recordType": "${recordtype}",\n "dateGenerated": "${luxon_1.DateTime.now().toISO()}",\n`);
10
10
  if (!_.isEmpty(modifiedBefore) || !_.isEmpty(modifiedAfter)) {
11
11
  this.push(`"dateModifiedRange": ${this.getDateModifiedRangeObject(modifiedBefore, modifiedAfter)},\n`);
12
12
  }
package/tsconfig.json CHANGED
File without changes
@@ -4,7 +4,7 @@ import {
4
4
 
5
5
  import { Sails, Model } from "sails";
6
6
  import { v1 as uuidv1 } from 'uuid';
7
- import moment = require('moment');
7
+ import { DateTime } from 'luxon';
8
8
 
9
9
  import mongodb = require('mongodb');
10
10
  import util = require('util');
@@ -162,8 +162,14 @@ export module Services {
162
162
  await Record.updateOne({ redboxOid: oid }).set(record);
163
163
  response.success = true;
164
164
  } catch (err) {
165
- sails.log.error(`${this.logHeader} Failed to save update to MongoDB:`);
166
- sails.log.error(JSON.stringify(err));
165
+ sails.log.error(`${this.logHeader} Failed to save update to MongoDB: ${JSON.stringify({
166
+ error: err,
167
+ response: response,
168
+ brand: brand,
169
+ oid: oid,
170
+ record: record,
171
+ user: user,
172
+ })}`);
167
173
  response.success = false;
168
174
  response.message = err;
169
175
  }
@@ -208,33 +214,55 @@ export module Services {
208
214
  return response;
209
215
  }
210
216
 
217
+ /**
218
+ * If pendingValue is in editPending or viewPending, remove all instances from the pending arrays and
219
+ * put the userid in the matching access / non-pending array, then save the changes to the storage.
220
+ *
221
+ * Implementation Note: This is a sync method, but it calls async methods.
222
+ * This means that the storage will not be updated when this method returns, but at some point later.
223
+ *
224
+ * @param oid The record identifier.
225
+ * @param userid The value to put in the matching access / non-pending arrays.
226
+ * @param pendingValue The value to find in the pending arrays.
227
+ */
211
228
  public provideUserAccessAndRemovePendingAccess(oid, userid, pendingValue): void {
212
229
  const batchFn = async () => {
213
230
  const metadata = await this.getMeta(oid);
214
- // remove pending edit access and add real edit access with userid
215
- var pendingEditArray = metadata['authorization']['editPending'];
216
- var editArray = metadata['authorization']['edit'];
217
- for (var i = 0; i < pendingEditArray.length; i++) {
218
- if (pendingEditArray[i] == pendingValue) {
219
- pendingEditArray = pendingEditArray.filter(e => e !== pendingValue);
220
- editArray = editArray.filter(e => e !== userid);
221
- editArray.push(userid);
222
- }
231
+
232
+ // Update edit authorization - remove pending edit access and add real edit access with userid
233
+ const pendingEditArray: string[] = _.get(metadata, 'authorization.editPending', []);
234
+ const editArray: string[] = _.get(metadata, 'authorization.edit', []);
235
+
236
+ // remove all items matching pendingValue from the pendingEditArray
237
+ const pendingEditArrayFiltered = pendingEditArray.filter(value => value !== pendingValue);
238
+ const pendingEditFound = pendingEditArray.length > pendingEditArrayFiltered.length;
239
+
240
+ // add the item to the editArray if it existed in the pendingEditArray, and it is not in the editArray
241
+ if (pendingEditFound && !editArray.includes(userid)) {
242
+ editArray.push(userid);
223
243
  }
224
- metadata['authorization']['editPending'] = pendingEditArray;
225
- metadata['authorization']['edit'] = editArray;
226
-
227
- var pendingViewArray = metadata['authorization']['viewPending'];
228
- var viewArray = metadata['authorization']['view'];
229
- for (var i = 0; i < pendingViewArray.length; i++) {
230
- if (pendingViewArray[i] == pendingValue) {
231
- pendingViewArray = pendingViewArray.filter(e => e !== pendingValue);
232
- viewArray = viewArray.filter(e => e !== userid);
233
- viewArray.push(userid);
234
- }
244
+
245
+ // update the metadata with the modified arrays
246
+ _.set(metadata, 'authorization.editPending', pendingEditArrayFiltered);
247
+ _.set(metadata, 'authorization.edit', editArray);
248
+
249
+ // Update view authorization - remove pending view access and add real view access with userid
250
+ const pendingViewArray: string[] = _.get(metadata, 'authorization.viewPending', []);
251
+ const viewArray: string[] = _.get(metadata, 'authorization.view', []);
252
+
253
+ // remove all items matching pendingValue from the pendingViewArray
254
+ const pendingViewArrayFiltered = pendingViewArray.filter(value => value !== pendingValue);
255
+ const pendingViewFound = pendingViewArray.length > pendingViewArrayFiltered.length;
256
+
257
+ // add the item to the viewArray if it existed in the pendingViewArray, and it is not in the viewArray
258
+ if (pendingViewFound && !viewArray.includes(userid)) {
259
+ viewArray.push(userid);
235
260
  }
236
- metadata['authorization']['viewPending'] = pendingViewArray;
237
- metadata['authorization']['view'] = viewArray;
261
+
262
+ // update the metadata with the modified arrays
263
+ _.set(metadata, 'authorization.viewPending', pendingViewArrayFiltered);
264
+ _.set(metadata, 'authorization.view', viewArray);
265
+
238
266
  try {
239
267
  await this.updateMeta(null, oid, metadata);
240
268
  } catch (err) {
@@ -242,6 +270,8 @@ export module Services {
242
270
  sails.log.error(JSON.stringify(err));
243
271
  }
244
272
  };
273
+
274
+ // TODO: Fix this so that the method only returns after the storage is updated.
245
275
  batchFn();
246
276
  }
247
277
 
@@ -345,7 +375,8 @@ export module Services {
345
375
  const logName = _.get(options, 'logName', null);
346
376
  if (logName) {
347
377
  let log = _.get(record, logName, null);
348
- const entry = { date: moment().format('YYYY-MM-DDTHH:mm:ss') };
378
+ // Use Luxon for ISO-like local timestamp without timezone offset
379
+ const entry = { date: DateTime.now().toFormat("yyyy-LL-dd'T'HH:mm:ss") };
349
380
  if (log) {
350
381
  log.push(entry);
351
382
  } else {
@@ -1,16 +1,16 @@
1
1
  'use strict';
2
2
 
3
- const {
4
- Transform
5
- } = require('stream');
6
- import moment = require('moment');
3
+ const { Transform } = require('stream');
4
+ import { DateTime } from 'luxon';
5
+ declare var require: any;
6
+ declare var module: any;
7
7
  declare let sails, _;
8
8
 
9
9
  class ExportJSONTransformer extends Transform {
10
10
  first:boolean = true;
11
11
  constructor(recordtype:string, modifiedBefore:string, modifiedAfter:string) {
12
12
  super();
13
- this.push(`{ "recordType": "${recordtype}",\n "dateGenerated": "${moment().toISOString()}",\n`)
13
+ this.push(`{ "recordType": "${recordtype}",\n "dateGenerated": "${DateTime.now().toISO()}",\n`)
14
14
  if(!_.isEmpty(modifiedBefore) || !_.isEmpty(modifiedAfter)) {
15
15
  this.push(`"dateModifiedRange": ${this.getDateModifiedRangeObject(modifiedBefore, modifiedAfter)},\n`);
16
16
  }
package/test/bootstrap.js DELETED
@@ -1,65 +0,0 @@
1
- var Sails = require('sails').Sails;
2
-
3
- describe('Bootstrap tests ::', function() {
4
- // Var to hold a running sails app instance
5
- var _sails;
6
- var appPath = '/opt/redbox-portal'
7
-
8
- // Before running any tests, attempt to lift Sails
9
- before(function (done) {
10
-
11
- // Hook will timeout in 10 seconds
12
- this.timeout(11000);
13
-
14
- // Attempt to lift sails
15
- Sails().lift({
16
- appPath: appPath,
17
- models: {
18
- migrate: 'drop'
19
- },
20
- datastores: {
21
- mongodb: {
22
- adapter: require(appPath+'/node_modules/sails-mongo'),
23
- url: "mongodb://mongodb:27017/redbox-portal"
24
- },
25
- redboxStorage: {
26
- adapter: require(appPath+'/node_modules/sails-mongo'),
27
- url: 'mongodb://mongodb:27017/redbox-storage'
28
- }
29
- },
30
- globals: {
31
- sails: true,
32
- _: require('lodash'),
33
- async: require('async'),
34
- models: true,
35
- services: true
36
- },
37
- hooks: {
38
- // Skip grunt (unless your hook uses it)
39
- "grunt": false
40
- },
41
- log: {level: "verbose"}
42
- },function (err, __sails) {
43
- if (err) return done(err);
44
- _sails = __sails;
45
- return done();
46
- });
47
- });
48
-
49
- // After tests are complete, lower Sails
50
- after(function (done) {
51
-
52
- // Lower Sails (if it successfully lifted)
53
- if (_sails) {
54
- return _sails.lower(done);
55
- }
56
- // Otherwise just return
57
- return done();
58
- });
59
-
60
- // Test that Sails can lift with the hook in place
61
- it ('sails does not crash', function() {
62
- return true;
63
- });
64
-
65
- });