spec-3nweb-server 1.3.8 → 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.
Files changed (95) hide show
  1. package/build/3nstorage/3nstorage-app.js +4 -4
  2. package/build/3nstorage/owner.js +28 -28
  3. package/build/3nstorage/resources/store.d.ts +2 -9
  4. package/build/3nstorage/resources/store.js +76 -73
  5. package/build/3nstorage/resources/users.d.ts +4 -2
  6. package/build/3nstorage/resources/users.js +8 -4
  7. package/build/3nstorage/routes/owner/archive-obj-version.d.ts +2 -2
  8. package/build/3nstorage/routes/owner/archive-obj-version.js +36 -31
  9. package/build/3nstorage/routes/owner/cancel-trans.js +1 -1
  10. package/build/3nstorage/routes/owner/delete-obj.d.ts +3 -2
  11. package/build/3nstorage/routes/owner/delete-obj.js +42 -7
  12. package/build/3nstorage/routes/owner/get-archived-obj-ver.js +10 -6
  13. package/build/3nstorage/routes/owner/get-current-obj.js +2 -2
  14. package/build/3nstorage/routes/owner/list-obj-archive.js +28 -31
  15. package/build/3nstorage/routes/owner/param-getter.js +3 -2
  16. package/build/3nstorage/routes/owner/param-setter.js +3 -2
  17. package/build/3nstorage/routes/owner/put-current-obj.js +12 -10
  18. package/build/3nstorage/routes/owner/session-params.js +4 -3
  19. package/build/admin/admin-app.js +5 -5
  20. package/build/admin/resources/users.js +42 -42
  21. package/build/admin/routes/add.js +3 -3
  22. package/build/admin/signup-tokens.js +8 -8
  23. package/build/asmail/asmail-app.js +7 -7
  24. package/build/asmail/config.js +9 -8
  25. package/build/asmail/delivery.js +10 -9
  26. package/build/asmail/resources/delivery-sessions.js +4 -3
  27. package/build/asmail/resources/inbox.d.ts +1 -1
  28. package/build/asmail/resources/inbox.js +22 -22
  29. package/build/asmail/resources/recipients.d.ts +2 -1
  30. package/build/asmail/resources/recipients.js +4 -4
  31. package/build/asmail/resources/sessions.js +2 -1
  32. package/build/asmail/retrieval.js +13 -8
  33. package/build/asmail/routes/config/param-getter.js +3 -2
  34. package/build/asmail/routes/config/param-setter.js +3 -2
  35. package/build/asmail/routes/delivery/finalize-delivery.js +3 -2
  36. package/build/asmail/routes/delivery/pre-flight.js +5 -4
  37. package/build/asmail/routes/delivery/provide-recipient-pubkey.js +3 -2
  38. package/build/asmail/routes/delivery/put-metadata.js +3 -2
  39. package/build/asmail/routes/delivery/put-obj.js +4 -4
  40. package/build/asmail/routes/delivery/restart-session.js +4 -3
  41. package/build/asmail/routes/delivery/sender-authorization.d.ts +1 -3
  42. package/build/asmail/routes/delivery/sender-authorization.js +3 -2
  43. package/build/asmail/routes/delivery/start-session.js +5 -4
  44. package/build/asmail/routes/retrieval/get-message-meta.js +3 -2
  45. package/build/asmail/routes/retrieval/get-message-obj.js +4 -3
  46. package/build/asmail/routes/retrieval/list-messages.js +3 -2
  47. package/build/asmail/routes/retrieval/remove-message.js +3 -2
  48. package/build/lib-common/async-fs-node.d.ts +2 -0
  49. package/build/lib-common/async-fs-node.js +13 -13
  50. package/build/lib-common/byte-streaming/common.js +9 -9
  51. package/build/lib-common/canonical-address.js +1 -1
  52. package/build/lib-common/ipc/generic-ipc.js +12 -12
  53. package/build/lib-common/ipc/ws-ipc.js +2 -2
  54. package/build/lib-common/mid-sigs-NaCl-Ed.js +14 -14
  55. package/build/lib-common/objs-on-disk/file-layout.js +10 -10
  56. package/build/lib-common/objs-on-disk/obj-file.js +11 -11
  57. package/build/lib-common/objs-on-disk/utils.d.ts +1 -0
  58. package/build/lib-common/objs-on-disk/utils.js +3 -3
  59. package/build/lib-common/processes.js +1 -1
  60. package/build/lib-common/random-node.js +7 -7
  61. package/build/lib-common/service-api/3nstorage/owner.d.ts +24 -18
  62. package/build/lib-common/service-api/3nstorage/owner.js +31 -26
  63. package/build/lib-common/service-api/asmail/delivery.js +2 -2
  64. package/build/lib-common/service-api/asmail/retrieval.js +1 -1
  65. package/build/lib-server/conf-util.js +2 -1
  66. package/build/lib-server/middleware/body-parsers.js +16 -16
  67. package/build/lib-server/middleware/error-handler.js +1 -1
  68. package/build/lib-server/resources/mailerid-authorizer.js +3 -3
  69. package/build/lib-server/resources/mem-backed-sessions-factory.js +3 -3
  70. package/build/lib-server/resources/server-data-folders.js +23 -23
  71. package/build/lib-server/resources/sessions.js +5 -5
  72. package/build/lib-server/resources/user-files.js +8 -8
  73. package/build/lib-server/routes/pub-key-login/complete-exchange.js +4 -3
  74. package/build/lib-server/routes/pub-key-login/start-exchange.js +7 -6
  75. package/build/lib-server/routes/sessions/mid-auth.js +6 -5
  76. package/build/lib-server/routes/sessions/start.js +4 -3
  77. package/build/lib-server/web-sockets/app.d.ts +1 -0
  78. package/build/lib-server/web-sockets/app.js +6 -5
  79. package/build/lib-server/web-sockets/server-events.js +5 -4
  80. package/build/mailerId/mailerId-app.js +7 -7
  81. package/build/mailerId/resources/certifier.d.ts +4 -6
  82. package/build/mailerId/resources/certifier.js +8 -7
  83. package/build/mailerId/resources/compute-login-dhshared-key.js +2 -1
  84. package/build/mailerId/resources/sessions.js +2 -1
  85. package/build/mailerId/resources/users.js +4 -4
  86. package/build/mailerId/routes/certify.js +1 -1
  87. package/build/main.js +10 -10
  88. package/build/mock/dns.js +1 -1
  89. package/build/mock/mock-as-child-proc.js +10 -10
  90. package/build/mock/node-child-ipc.js +2 -2
  91. package/build/mock/run-in-proc.js +7 -7
  92. package/build/run-config.js +10 -10
  93. package/build/run.js +4 -4
  94. package/build/services.js +5 -5
  95. package/package.json +13 -10
@@ -44,13 +44,13 @@ function setupStaticEntryRoute(app) {
44
44
  }
45
45
  function makeApp(dataFolder, domain, midAuthorizer) {
46
46
  const app = new app_1.AppWithWSs();
47
- const ownersSessions = sessions_1.makeSessionFactory(20 * 60);
48
- const sharingSessions = sessions_1.makeSessionFactory(20 * 60);
49
- const users = users_1.makeFactory(dataFolder);
47
+ const ownersSessions = (0, sessions_1.makeSessionFactory)(20 * 60);
48
+ const sharingSessions = (0, sessions_1.makeSessionFactory)(20 * 60);
49
+ const users = (0, users_1.makeFactory)(dataFolder);
50
50
  setupStaticEntryRoute(app.http);
51
51
  app.use(PATHS.owner, owners.makeApp(domain, ownersSessions, users, midAuthorizer));
52
52
  app.http.use(PATHS.shared, sharing.makeApp(sharingSessions, users));
53
- app.http.use(error_handler_1.makeErrHandler((err, req) => {
53
+ app.http.use((0, error_handler_1.makeErrHandler)((err, req) => {
54
54
  if (typeof err.status !== 'number') {
55
55
  console.error(`\n --- Error occured in storage, when handling ${req.method} request to ${req.originalUrl}`);
56
56
  console.error(err);
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2015 - 2017 3NSoft Inc.
3
+ Copyright (C) 2015 - 2017, 2022 3NSoft Inc.
4
4
 
5
5
  This program is free software: you can redistribute it and/or modify it under
6
6
  the terms of the GNU General Public License as published by the Free Software
@@ -59,44 +59,44 @@ const MAX_CHUNK_SIZE = '0.5mb';
59
59
  function setHttpPart(app, domain, sessions, users, midAuthorizer) {
60
60
  app.http.disable('etag');
61
61
  // Login
62
- app.http.post('/' + api.midLogin.START_URL_END, sessions.checkSession(), body_parsers_1.json('1kb'), start_1.startSession(users.exists, sessions.generate));
63
- app.http.post('/' + api.midLogin.AUTH_URL_END, sessions.ensureOpenedSession(), body_parsers_1.json('4kb'), mid_auth_1.midLogin(domain, midAuthorizer));
62
+ app.http.post('/' + api.midLogin.START_URL_END, sessions.checkSession(), (0, body_parsers_1.json)('1kb'), (0, start_1.startSession)(users.exists, sessions.generate));
63
+ app.http.post('/' + api.midLogin.AUTH_URL_END, sessions.ensureOpenedSession(), (0, body_parsers_1.json)('4kb'), (0, mid_auth_1.midLogin)(domain, midAuthorizer));
64
64
  // *** Require authorized session for everything below ***
65
65
  app.http.use(sessions.ensureAuthorizedSession());
66
- app.http.post('/' + api.closeSession.URL_END, body_parsers_1.emptyBody(), close_1.closeSession());
66
+ app.http.post('/' + api.closeSession.URL_END, (0, body_parsers_1.emptyBody)(), (0, close_1.closeSession)());
67
67
  // Session params
68
- app.http.get('/' + api.sessionParams.URL_END, session_params_1.sessionParams(MAX_CHUNK_SIZE));
68
+ app.http.get('/' + api.sessionParams.URL_END, (0, session_params_1.sessionParams)(MAX_CHUNK_SIZE));
69
69
  // Key derivation params
70
70
  app.http.route('/' + api.keyDerivParams.URL_END)
71
- .get(param_getter_1.getParam(users.getKeyDerivParams))
72
- .put(body_parsers_1.json('1kb'), param_setter_1.setParam(users.setKeyDerivParams));
71
+ .get((0, param_getter_1.getParam)(users.getKeyDerivParams))
72
+ .put((0, body_parsers_1.json)('1kb'), (0, param_setter_1.setParam)(users.setKeyDerivParams));
73
73
  // Transaction canceling
74
- app.http.post('/' + api.cancelTransaction.EXPRESS_URL_END, body_parsers_1.emptyBody(), cancel_trans_1.cancelTransaction(false, users.cancelTransaction));
75
- app.http.post('/' + api.cancelRootTransaction.EXPRESS_URL_END, body_parsers_1.emptyBody(), cancel_trans_1.cancelTransaction(true, users.cancelTransaction));
76
- // Getting current root object
74
+ app.http.post('/' + api.cancelTransaction.EXPRESS_URL_END, (0, body_parsers_1.emptyBody)(), (0, cancel_trans_1.cancelTransaction)(false, users.cancelTransaction));
75
+ app.http.post('/' + api.cancelRootTransaction.EXPRESS_URL_END, (0, body_parsers_1.emptyBody)(), (0, cancel_trans_1.cancelTransaction)(true, users.cancelTransaction));
76
+ // Getting and updating current root object
77
77
  app.http.route('/' + api.currentRootObj.EXPRESS_URL_END)
78
- .get(get_current_obj_1.getCurrentObj(true, users.getCurrentRootObj))
79
- .put(put_current_obj_1.saveCurrentObj(true, users.saveNewRootVersion, MAX_CHUNK_SIZE));
80
- // Getting current non-root objects
78
+ .get((0, get_current_obj_1.getCurrentObj)(true, users.getCurrentRootObj))
79
+ .put((0, put_current_obj_1.saveCurrentObj)(true, users.saveNewRootVersion, MAX_CHUNK_SIZE));
80
+ // Getting, updating and removing current non-root objects
81
81
  app.http.route('/' + api.currentObj.EXPRESS_URL_END)
82
- .get(get_current_obj_1.getCurrentObj(false, users.getCurrentObj))
83
- .delete(delete_obj_1.deleteObj(false, true, users.deleteObj))
84
- .put(put_current_obj_1.saveCurrentObj(false, users.saveNewObjVersion, MAX_CHUNK_SIZE));
82
+ .get((0, get_current_obj_1.getCurrentObj)(false, users.getCurrentObj))
83
+ .delete((0, delete_obj_1.deleteCurrentObjVer)(users.deleteCurrentObjVersion))
84
+ .put((0, put_current_obj_1.saveCurrentObj)(false, users.saveNewObjVersion, MAX_CHUNK_SIZE));
85
+ // Getting root archived versions
86
+ app.http.route('/' + api.archivedRootVersion.EXPRESS_URL_END)
87
+ .get((0, get_archived_obj_ver_1.getArchivedObjVersion)(true, users.getArchivedRootVersion));
88
+ // Getting non-root object archived versions
89
+ app.http.route('/' + api.archivedObjVersion.EXPRESS_URL_END)
90
+ .get((0, get_archived_obj_ver_1.getArchivedObjVersion)(false, users.getArchivedObjVersion));
85
91
  // Archive root's current version
86
92
  app.http.route('/' + api.archiveRoot.URL_END)
87
- .get(list_obj_archive_1.listObjArchive(true, users.listObjArchive))
88
- .put(body_parsers_1.emptyBody(), archive_obj_version_1.archiveCurrentObjVersion(true, users.archiveObjVersion));
93
+ .get((0, list_obj_archive_1.listObjArchive)(true, users.listObjArchive))
94
+ .post((0, body_parsers_1.emptyBody)(), (0, archive_obj_version_1.archiveCurrentObjVersion)(true, users.archiveObjVersion))
95
+ .delete((0, delete_obj_1.deleteArchivedObjVer)(true, users.deleteArchivedObjVersion));
89
96
  // Archive non-root object's current version
90
97
  app.http.route('/' + api.archiveObj.EXPRESS_URL_END)
91
- .get(list_obj_archive_1.listObjArchive(false, users.listObjArchive))
92
- .put(body_parsers_1.emptyBody(), archive_obj_version_1.archiveCurrentObjVersion(false, users.archiveObjVersion));
93
- // Archived root versions
94
- app.http.route('/' + api.archivedRootVersion.EXPRESS_URL_END)
95
- .get(get_archived_obj_ver_1.getArchivedObjVersion(true, users.getArchivedRootVersion))
96
- .delete(delete_obj_1.deleteObj(true, false, users.deleteObj));
97
- // Removing archived and current versions of non-root object
98
- app.http.route('/' + api.archivedObjVersion.EXPRESS_URL_END)
99
- .get(get_archived_obj_ver_1.getArchivedObjVersion(true, users.getArchivedObjVersion))
100
- .delete(delete_obj_1.deleteObj(false, false, users.deleteObj));
98
+ .get((0, list_obj_archive_1.listObjArchive)(false, users.listObjArchive))
99
+ .post((0, body_parsers_1.emptyBody)(), (0, archive_obj_version_1.archiveCurrentObjVersion)(false, users.archiveObjVersion))
100
+ .delete((0, delete_obj_1.deleteArchivedObjVer)(false, users.deleteArchivedObjVersion));
101
101
  }
102
102
  Object.freeze(exports);
@@ -102,15 +102,8 @@ export declare class Store extends UserFiles {
102
102
  getArchivedObjVersion(objId: string | null, version: number, header: boolean, segsOffset: number, segsLimit: number | undefined): Promise<ObjReader>;
103
103
  private makeObjReader;
104
104
  private getObjFile;
105
- /**
106
- * @param objId is a string object id for non-root objects, and null for
107
- * root object.
108
- * @param archVersion is an optional parameter, identifying archived version
109
- * to delete. Default null value indicates that an object should be removed.
110
- * If an object has any archived versions (even if current), these will not
111
- * be removed, and such object state will be labeled as archived.
112
- */
113
- deleteObj(objId: string, archVersion?: number | null): Promise<void>;
105
+ deleteCurrentObjVer(objId: string, version?: number | null): Promise<void>;
106
+ deleteArchivedObjVer(objId: string | null, version: number): Promise<void>;
114
107
  /**
115
108
  * @param objId is a string object id for non-root objects, and null for
116
109
  * root object.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2015 - 2017, 2019 - 2020 3NSoft Inc.
3
+ Copyright (C) 2015 - 2017, 2019 - 2020, 2022 3NSoft Inc.
4
4
 
5
5
  This program is free software: you can redistribute it and/or modify it under
6
6
  the terms of the GNU General Public License as published by the Free Software
@@ -131,7 +131,7 @@ class Store extends user_files_1.UserFiles {
131
131
  Object.freeze(this);
132
132
  }
133
133
  static async make(userFolder, userId, storageEventsSink, writeBufferSize, readBufferSize) {
134
- const path = path_1.join(userFolder, 'store');
134
+ const path = (0, path_1.join)(userFolder, 'store');
135
135
  const store = new Store(userId, path, storageEventsSink, writeBufferSize, readBufferSize);
136
136
  await store.ensureUserExistsOnDisk();
137
137
  return store;
@@ -153,7 +153,7 @@ class Store extends user_files_1.UserFiles {
153
153
  await spaceTracker.change(this, byteLen);
154
154
  }
155
155
  const params = {
156
- isNewObj: (opts.ver === 1),
156
+ isNewObj: opts.create,
157
157
  version: opts.ver,
158
158
  baseVersion: (diff ? diff.baseVersion : undefined)
159
159
  };
@@ -163,10 +163,10 @@ class Store extends user_files_1.UserFiles {
163
163
  const filePath = this.transactions.objFileWritingPath(objId);
164
164
  file = await this.objVerFiles.forNewFile(objId, trans.version, filePath);
165
165
  if (diff) {
166
- await file.setSegsLayout(utils_1.diffToLayout(diff), false);
166
+ await file.setSegsLayout((0, utils_1.diffToLayout)(diff), false);
167
167
  }
168
- const chunks = utils_1.chunksInOrderedStream(byteLen, opts.header, 0);
169
- await utils_1.streamToObjFile(file, chunks, bytes, this.fileWritingBufferSize);
168
+ const chunks = (0, utils_1.chunksInOrderedStream)(byteLen, opts.header, 0);
169
+ await (0, utils_1.streamToObjFile)(file, chunks, bytes, this.fileWritingBufferSize);
170
170
  if (opts.last) {
171
171
  if (!file.isFileComplete()) {
172
172
  throw exports.SC.OBJ_FILE_INCOMPLETE;
@@ -183,7 +183,7 @@ class Store extends user_files_1.UserFiles {
183
183
  }
184
184
  catch (err) {
185
185
  await spaceTracker.change(this, -byteLen);
186
- await this.transactions.cancel(objId, trans.transactionId).catch(() => { });
186
+ await this.transactions.cancel(objId, trans.transactionId).catch(noop);
187
187
  throw err;
188
188
  }
189
189
  }
@@ -206,8 +206,8 @@ class Store extends user_files_1.UserFiles {
206
206
  const file = await this.objVerFiles.forExistingFile(objId, trans.version, filePath);
207
207
  if (byteLen > 0) {
208
208
  await spaceTracker.change(this, byteLen);
209
- const chunks = utils_1.chunksInOrderedStream(byteLen, undefined, opts.ofs);
210
- await utils_1.streamToObjFile(file, chunks, bytes, this.fileWritingBufferSize);
209
+ const chunks = (0, utils_1.chunksInOrderedStream)(byteLen, undefined, opts.ofs);
210
+ await (0, utils_1.streamToObjFile)(file, chunks, bytes, this.fileWritingBufferSize);
211
211
  }
212
212
  if (opts.last) {
213
213
  if (!file.isFileComplete()) {
@@ -302,75 +302,76 @@ class Store extends user_files_1.UserFiles {
302
302
  len: (segBytesToRead + headerLen),
303
303
  segsLen,
304
304
  headerLen,
305
- pipe: utils_1.makeObjPipe(file, true, segsOfs, segBytesToRead, objId, this.getObjFile)
305
+ pipe: (0, utils_1.makeObjPipe)(file, true, segsOfs, segBytesToRead, objId, this.getObjFile)
306
306
  };
307
307
  }
308
308
  else {
309
309
  reader = {
310
310
  len: segBytesToRead,
311
311
  segsLen,
312
- pipe: utils_1.makeObjPipe(file, false, segsOfs, segBytesToRead, objId, this.getObjFile)
312
+ pipe: (0, utils_1.makeObjPipe)(file, false, segsOfs, segBytesToRead, objId, this.getObjFile)
313
313
  };
314
314
  }
315
315
  Object.freeze(reader);
316
316
  return reader;
317
317
  }
318
- /**
319
- * @param objId is a string object id for non-root objects, and null for
320
- * root object.
321
- * @param archVersion is an optional parameter, identifying archived version
322
- * to delete. Default null value indicates that an object should be removed.
323
- * If an object has any archived versions (even if current), these will not
324
- * be removed, and such object state will be labeled as archived.
325
- */
326
- async deleteObj(objId, archVersion = null) {
318
+ async deleteCurrentObjVer(objId, version = null) {
319
+ if (!objId) {
320
+ throw new Error('Root object is not removable.');
321
+ }
327
322
  const status = await this.statuses.get(objId);
328
- const arch = status.archivedVersions;
323
+ if (status.state !== 'current') {
324
+ throw exports.SC.OBJ_UNKNOWN;
325
+ }
326
+ if (version && (version !== status.currentVersion)) {
327
+ throw exports.SC.OBJ_VER_UNKNOWN;
328
+ }
329
329
  // XXX need to put removal transaction, closing it in a finally clause
330
- if (archVersion === null) {
331
- if (objId === null) {
332
- throw new Error('Root object is not removable.');
333
- }
334
- if (status.state !== 'current') {
335
- throw exports.SC.OBJ_UNKNOWN;
336
- }
337
- if (!Array.isArray(arch) || (arch.length === 0)) {
338
- await this.statuses.deleteWithObj(objId);
339
- }
340
- else {
341
- const currVer = status.currentVersion;
342
- delete status.currentVersion;
343
- status.state = 'archived';
344
- await this.statuses.set(objId, status);
345
- if (typeof currVer !== 'number') {
346
- throw new Error(`Illegal state of object status file for ${objId}: state is current, while current version is missing.`);
347
- }
348
- if (arch.indexOf(currVer) < 0) {
349
- await this.rmObjFiles(objId, currVer);
350
- }
351
- }
330
+ const arch = status.archivedVersions;
331
+ if (!Array.isArray(arch) || (arch.length === 0)) {
332
+ // remove everything related to this object
333
+ await this.statuses.deleteWithObj(objId);
352
334
  }
353
335
  else {
354
- if (!Array.isArray(arch)) {
355
- throw exports.SC.OBJ_UNKNOWN;
356
- }
357
- const indInArch = arch.indexOf(archVersion);
358
- if (indInArch < 0) {
359
- throw exports.SC.OBJ_UNKNOWN;
360
- }
361
- arch.splice(indInArch, 1);
362
- if (arch.length === 0) {
363
- delete status.archivedVersions;
364
- }
336
+ // set status and remove version if it isn't archived
337
+ version = status.currentVersion;
338
+ delete status.currentVersion;
339
+ status.state = 'archived';
365
340
  await this.statuses.set(objId, status);
366
- if (status.currentVersion !== archVersion) {
367
- await this.rmObjFiles(objId, archVersion);
341
+ if (arch.indexOf(version) < 0) {
342
+ await this.rmObjFiles(objId, version);
368
343
  }
369
344
  }
370
345
  this.storageEventsSink(this.userId, owner_1.objRemoved.EVENT_NAME, {
371
346
  objId,
372
347
  });
373
348
  }
349
+ async deleteArchivedObjVer(objId, version) {
350
+ const status = await this.statuses.get(objId);
351
+ const arch = status.archivedVersions;
352
+ // XXX need to put removal transaction, closing it in a finally clause
353
+ if (!Array.isArray(arch)) {
354
+ throw exports.SC.OBJ_VER_UNKNOWN;
355
+ }
356
+ const indInArch = arch.indexOf(version);
357
+ if (indInArch < 0) {
358
+ throw exports.SC.OBJ_VER_UNKNOWN;
359
+ }
360
+ arch.splice(indInArch, 1);
361
+ if (arch.length === 0) {
362
+ delete status.archivedVersions;
363
+ }
364
+ await this.statuses.set(objId, status);
365
+ if (!status.archivedVersions && !status.currentVersion) {
366
+ await this.rmObjFiles(objId, version);
367
+ }
368
+ else if (status.currentVersion !== version) {
369
+ await this.statuses.deleteWithObj(objId);
370
+ }
371
+ // this.storageEventsSink(this.userId, objRemoved.EVENT_NAME, {
372
+ // objId,
373
+ // });
374
+ }
374
375
  /**
375
376
  * @param objId is a string object id for non-root objects, and null for
376
377
  * root object.
@@ -391,10 +392,10 @@ class Store extends user_files_1.UserFiles {
391
392
  const verPart = toFName(version);
392
393
  objFiles = objFiles.filter(fName => fName.startsWith(verPart));
393
394
  if (objFiles.length === 0) {
394
- throw exports.SC.OBJ_UNKNOWN;
395
+ throw exports.SC.OBJ_VER_UNKNOWN;
395
396
  }
396
397
  for (const fName of objFiles) {
397
- await fs.unlink(path_1.join(objFolder, fName)).catch(() => { });
398
+ await fs.unlink((0, path_1.join)(objFolder, fName)).catch(() => { });
398
399
  }
399
400
  }
400
401
  // XXX need both, archiving and removal transactions for atomic locking
@@ -404,12 +405,13 @@ class Store extends user_files_1.UserFiles {
404
405
  // file/folder.
405
406
  async archiveCurrentObjVersion(objId, version) {
406
407
  // XXX need to put archiving transaction, closing it in a finally clause
408
+ // - make in memory transactions for archival and removal, or chaining(?)
407
409
  const status = await this.statuses.get(objId);
408
410
  if (status.state !== 'current') {
409
411
  throw exports.SC.OBJ_UNKNOWN;
410
412
  }
411
- if (typeof status.currentVersion !== 'number') {
412
- throw new Error(`Illegal state of object status file for ${objId}: state is current, while current version is missing.`);
413
+ if (status.currentVersion !== version) {
414
+ throw exports.SC.OBJ_VER_UNKNOWN;
413
415
  }
414
416
  const arch = status.archivedVersions;
415
417
  if (Array.isArray(arch)) {
@@ -501,8 +503,8 @@ class ObjStatuses {
501
503
  }
502
504
  objFolder(objId) {
503
505
  return (objId ?
504
- path_1.join(this.path, 'objects', objId) :
505
- path_1.join(this.path, 'root'));
506
+ (0, path_1.join)(this.path, 'objects', objId) :
507
+ (0, path_1.join)(this.path, 'root'));
506
508
  }
507
509
  async get(objId) {
508
510
  let status = this.cache.get(objId);
@@ -513,7 +515,7 @@ class ObjStatuses {
513
515
  return status;
514
516
  }
515
517
  async fromFile(objId) {
516
- const filePath = path_1.join(this.objFolder(objId), STATUS_FILE);
518
+ const filePath = (0, path_1.join)(this.objFolder(objId), STATUS_FILE);
517
519
  const str = await fs.readFile(filePath, { encoding: 'utf8', flag: 'r' }).catch((exc) => {
518
520
  if (exc.notFound) {
519
521
  throw exports.SC.OBJ_UNKNOWN;
@@ -524,7 +526,7 @@ class ObjStatuses {
524
526
  return JSON.parse(str);
525
527
  }
526
528
  catch (err) {
527
- throw error_1.errWithCause(err, `Can't parse content of obj status file`);
529
+ throw (0, error_1.errWithCause)(err, `Can't parse content of obj status file`);
528
530
  }
529
531
  }
530
532
  async set(objId, status) {
@@ -532,7 +534,7 @@ class ObjStatuses {
532
534
  await this.saveToFile(objId, status);
533
535
  }
534
536
  async saveToFile(objId, status) {
535
- const filePath = path_1.join(this.objFolder(objId), STATUS_FILE);
537
+ const filePath = (0, path_1.join)(this.objFolder(objId), STATUS_FILE);
536
538
  const str = JSON.stringify(status);
537
539
  const procId = (objId ? objId : 'null');
538
540
  await this.saveProcs.startOrChain(procId, () => fs.writeFile(filePath, str, { encoding: 'utf8', flag: 'w' }));
@@ -540,7 +542,7 @@ class ObjStatuses {
540
542
  async deleteWithObj(objId) {
541
543
  this.cache.delete(objId);
542
544
  if (objId === null) {
543
- await fs.unlink(path_1.join(this.objFolder(null), STATUS_FILE))
545
+ await fs.unlink((0, path_1.join)(this.objFolder(null), STATUS_FILE))
544
546
  .catch(() => { });
545
547
  }
546
548
  else {
@@ -571,7 +573,7 @@ class ObjStatuses {
571
573
  });
572
574
  }
573
575
  objFileReadingPath(objId, version) {
574
- return path_1.join(this.objFolder(objId), toFName(version));
576
+ return (0, path_1.join)(this.objFolder(objId), toFName(version));
575
577
  }
576
578
  }
577
579
  Object.freeze(ObjStatuses.prototype);
@@ -587,8 +589,8 @@ class ObjTransactions {
587
589
  }
588
590
  transactionFolder(objId) {
589
591
  return (objId ?
590
- path_1.join(this.path, 'transactions', objId) :
591
- path_1.join(this.path, 'root', 'transaction'));
592
+ (0, path_1.join)(this.path, 'transactions', objId) :
593
+ (0, path_1.join)(this.path, 'root', 'transaction'));
592
594
  }
593
595
  async get(objId, transactionId) {
594
596
  let isInCache = true;
@@ -606,7 +608,7 @@ class ObjTransactions {
606
608
  return trans;
607
609
  }
608
610
  transactionFilePath(objId) {
609
- return path_1.join(this.transactionFolder(objId), 'transaction');
611
+ return (0, path_1.join)(this.transactionFolder(objId), 'transaction');
610
612
  }
611
613
  async fromFile(objId) {
612
614
  const filePath = this.transactionFilePath(objId);
@@ -625,7 +627,7 @@ class ObjTransactions {
625
627
  return JSON.parse(str);
626
628
  }
627
629
  catch (err) {
628
- throw error_1.errWithCause(err, `Can't parse content of obj transaction file`);
630
+ throw (0, error_1.errWithCause)(err, `Can't parse content of obj transaction file`);
629
631
  }
630
632
  }
631
633
  async set(objId, status) {
@@ -639,11 +641,11 @@ class ObjTransactions {
639
641
  await this.saveProcs.startOrChain(procId, () => fs.writeFile(filePath, str, { encoding: 'utf8', flag: 'w' }));
640
642
  }
641
643
  objFileWritingPath(objId) {
642
- return path_1.join(this.transactionFolder(objId), 'new');
644
+ return (0, path_1.join)(this.transactionFolder(objId), 'new');
643
645
  }
644
646
  async startNew(objId, reqTrans) {
645
647
  const trans = reqTrans;
646
- trans.transactionId = await random_node_1.stringOfB64UrlSafeChars(10);
648
+ trans.transactionId = await (0, random_node_1.stringOfB64UrlSafeChars)(10);
647
649
  trans.transactionType = 'write';
648
650
  await this.makeTransactionFolder(objId);
649
651
  await this.set(objId, trans);
@@ -735,4 +737,5 @@ Object.freeze(ObjStatuses);
735
737
  function toFName(version) {
736
738
  return `${version}.`;
737
739
  }
740
+ function noop() { }
738
741
  Object.freeze(exports);
@@ -18,7 +18,8 @@ export declare type GetArchivedObjVersion = (userId: string, objId: string | nul
18
18
  export declare type CancelTransaction = (userId: string, objId: string, transactionId?: string) => Promise<void>;
19
19
  export declare type ArchiveObjCurrentVersion = (userId: string, objId: string, version: number) => Promise<void>;
20
20
  export declare type ListObjArchive = (userId: string, objId: string) => Promise<number[]>;
21
- export declare type DeleteObj = (userId: string, objId: string, version: number) => Promise<void>;
21
+ export declare type DeleteCurrentObjVersion = (userId: string, objId: string, version?: number) => Promise<void>;
22
+ export declare type DeleteArchivedObjVersion = (userId: string, objId: string | null, version: number) => Promise<void>;
22
23
  declare type GetParam<T> = (userId: string) => Promise<T>;
23
24
  declare type SetParam<T> = (userId: string, param: T) => Promise<boolean>;
24
25
  export declare type GetSpaceQuota = GetParam<number>;
@@ -42,7 +43,8 @@ export interface Factory {
42
43
  archiveObjVersion: ArchiveObjCurrentVersion;
43
44
  getArchivedRootVersion: GetArchivedObjVersion;
44
45
  getArchivedObjVersion: GetArchivedObjVersion;
45
- deleteObj: DeleteObj;
46
+ deleteCurrentObjVersion: DeleteCurrentObjVersion;
47
+ deleteArchivedObjVersion: DeleteArchivedObjVersion;
46
48
  setStorageEventsSink(sink: EventsSink): void;
47
49
  }
48
50
  export declare function makeFactory(rootFolder: string, writeBufferSize?: string | number, readBufferSize?: string | number): Factory;
@@ -16,7 +16,7 @@
16
16
  this program. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
- exports.makeFactory = void 0;
19
+ exports.makeFactory = exports.SC = void 0;
20
20
  const store_1 = require("./store");
21
21
  const server_data_folders_1 = require("../../lib-server/resources/server-data-folders");
22
22
  var store_2 = require("./store");
@@ -40,7 +40,7 @@ function makeFactory(rootFolder, writeBufferSize, readBufferSize) {
40
40
  }
41
41
  }
42
42
  else {
43
- const userFolder = server_data_folders_1.userDataInRootFolder(rootFolder, userId);
43
+ const userFolder = (0, server_data_folders_1.userDataInRootFolder)(rootFolder, userId);
44
44
  const store = await store_1.Store.make(userFolder, userId, storageEventsSink, writeBufferSize, readBufferSize);
45
45
  stores.set(userId, store);
46
46
  return store;
@@ -122,9 +122,9 @@ function makeFactory(rootFolder, writeBufferSize, readBufferSize) {
122
122
  saveNewRootVersion: makeObjSaver(true),
123
123
  saveNewObjVersion: makeObjSaver(false),
124
124
  cancelTransaction: makeTransactionCanceller(),
125
- deleteObj: async (userId, objId, version) => {
125
+ deleteCurrentObjVersion: async (userId, objId, version) => {
126
126
  const store = await getStore(userId);
127
- await store.deleteObj(objId, version);
127
+ await store.deleteCurrentObjVer(objId, version);
128
128
  },
129
129
  archiveObjVersion: async (userId, objId, version) => {
130
130
  const store = await getStore(userId);
@@ -134,6 +134,10 @@ function makeFactory(rootFolder, writeBufferSize, readBufferSize) {
134
134
  const store = await getStore(userId);
135
135
  return store.listObjArchive(objId);
136
136
  },
137
+ deleteArchivedObjVersion: async (userId, objId, version) => {
138
+ const store = await getStore(userId);
139
+ await store.deleteArchivedObjVer(objId, version);
140
+ },
137
141
  setStorageEventsSink(sink) {
138
142
  if (storageEventsSink) {
139
143
  throw new Error(`Storage events sink is already set`);
@@ -1,3 +1,3 @@
1
- import * as express from 'express';
1
+ import { RequestHandler } from 'express';
2
2
  import { ArchiveObjCurrentVersion } from '../../resources/users';
3
- export declare function archiveCurrentObjVersion(root: boolean, archiveObjVerFunc: ArchiveObjCurrentVersion): express.RequestHandler;
3
+ export declare function archiveCurrentObjVersion(root: boolean, archiveObjVerFunc: ArchiveObjCurrentVersion): RequestHandler;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2016 3NSoft Inc.
3
+ Copyright (C) 2022 3NSoft Inc.
4
4
 
5
5
  This program is free software: you can redistribute it and/or modify it under
6
6
  the terms of the GNU General Public License as published by the Free Software
@@ -13,44 +13,49 @@
13
13
  See the GNU General Public License for more details.
14
14
 
15
15
  You should have received a copy of the GNU General Public License along with
16
- this program. If not, see <http://www.gnu.org/licenses/>. */
16
+ this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
17
18
  Object.defineProperty(exports, "__esModule", { value: true });
18
19
  exports.archiveCurrentObjVersion = void 0;
20
+ const users_1 = require("../../resources/users");
19
21
  const owner_1 = require("../../../lib-common/service-api/3nstorage/owner");
20
22
  const SC = owner_1.archiveObj.SC;
21
23
  function archiveCurrentObjVersion(root, archiveObjVerFunc) {
22
24
  if ('function' !== typeof archiveObjVerFunc) {
23
25
  throw new TypeError("Given argument 'archiveObjVerFunc' must be function, but is not.");
24
26
  }
25
- return async function (req, res, next) {
26
- next(new Error('Not implemented, yet.'));
27
- // const userId = req.session.params.userId;
28
- // const objId: string = (root ? null : req.params.objId);
29
- // const version: number = (delCurrent ? null : req.params.version);
30
- // try {
31
- // await deleteObjFunc(userId, objId, version);
32
- // res.status(SC.ok).end();
33
- // } catch (err) {
34
- // if ("string" !== typeof err) {
35
- // next(err);
36
- // } else if (err === storeSC.CONCURRENT_TRANSACTION) {
37
- // res.status(SC.concurrentTransaction).send(
38
- // `Object ${objId} is currently under a transaction.`);
39
- // } else if (err === storeSC.OBJ_UNKNOWN) {
40
- // res.status(SC.unknownObj).send((version === null) ?
41
- // `Object ${objId} is unknown.` :
42
- // `Object ${objId} version ${version} is unknown.`);
43
- // } else if (err === storeSC.WRONG_OBJ_STATE) {
44
- // res.status(SC.incompatibleObjState).send(
45
- // `Object ${objId} is in a state, that does not allow to procede with this request.`);
46
- // } else if (err === storeSC.USER_UNKNOWN) {
47
- // res.status(api.ERR_SC.server).send(
48
- // "Recipient disappeared from the system.");
49
- // req.session.close();
50
- // } else {
51
- // next(new Error("Unhandled storage error code: "+err));
52
- // }
53
- // }
27
+ return async (req, res, next) => {
28
+ const userId = req.session.params.userId;
29
+ const objId = (root ? null : req.params.objId);
30
+ const version = parseInt(req.query.ver);
31
+ if (isNaN(version) || (version < 1)) {
32
+ res.status(owner_1.ERR_SC.malformed).send("Bad query parameters");
33
+ return;
34
+ }
35
+ try {
36
+ await archiveObjVerFunc(userId, objId, version);
37
+ res.status(SC.okPost).end();
38
+ }
39
+ catch (err) {
40
+ if ("string" !== typeof err) {
41
+ next(err);
42
+ }
43
+ else if (err === users_1.SC.OBJ_VER_UNKNOWN) {
44
+ res.status(SC.unknownObjVer).send(`Object ${objId} version ${version} is not current.`);
45
+ }
46
+ else if (err === users_1.SC.OBJ_UNKNOWN) {
47
+ res.status(SC.unknownObj).send(root ?
48
+ `Root object is not set.` :
49
+ `Object ${objId} is unknown.`);
50
+ }
51
+ else if (err === users_1.SC.USER_UNKNOWN) {
52
+ res.status(owner_1.ERR_SC.server).send("Recipient disappeared from the system.");
53
+ req.session.close();
54
+ }
55
+ else {
56
+ next(new Error("Unhandled storage error code: " + err));
57
+ }
58
+ }
54
59
  };
55
60
  }
56
61
  exports.archiveCurrentObjVersion = archiveCurrentObjVersion;
@@ -23,7 +23,7 @@ function cancelTransaction(root, cancelTransFunc) {
23
23
  if ('function' !== typeof cancelTransFunc) {
24
24
  throw new TypeError("Given argument 'cancelTransFunc' must be function, but is not.");
25
25
  }
26
- return async function (req, res, next) {
26
+ return async (req, res, next) => {
27
27
  const userId = req.session.params.userId;
28
28
  const objId = (root ? null : req.params.objId);
29
29
  const transactionId = req.params.transactionId;
@@ -1,3 +1,4 @@
1
1
  import { RequestHandler } from 'express';
2
- import { DeleteObj } from '../../resources/users';
3
- export declare function deleteObj(root: boolean, delCurrent: boolean, deleteObjFunc: DeleteObj): RequestHandler;
2
+ import { DeleteArchivedObjVersion, DeleteCurrentObjVersion } from '../../resources/users';
3
+ export declare function deleteCurrentObjVer(deleteObjFunc: DeleteCurrentObjVersion): RequestHandler;
4
+ export declare function deleteArchivedObjVer(root: boolean, deleteObjFunc: DeleteArchivedObjVersion): RequestHandler;