spec-3nweb-server 1.8.4 → 1.8.6
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/.gitlab-ci-linux.yml +50 -0
- package/.gitlab-ci-mac.yml +29 -0
- package/.gitlab-ci-windows.yml +29 -0
- package/.gitlab-ci.yml +63 -0
- package/build/3nstorage/routes/owner/archive-obj-version.js +2 -2
- package/build/3nstorage/routes/owner/cancel-trans.js +2 -2
- package/build/3nstorage/routes/owner/delete-obj.js +2 -2
- package/build/3nstorage/routes/owner/get-current-obj.js +3 -4
- package/build/3nstorage/routes/owner/param-setter.js +2 -6
- package/build/asmail/routes/config/param-setter.js +2 -2
- package/build/asmail/routes/delivery/finalize-delivery.js +2 -2
- package/build/asmail/routes/delivery/put-obj.js +2 -2
- package/build/asmail/routes/delivery/sender-authorization.js +2 -2
- package/build/asmail/routes/retrieval/remove-message.js +2 -2
- package/build/cli/signup-cmd.js +0 -1
- package/build/lib-server/routes/sessions/close.js +2 -2
- package/build/lib-server/routes/sessions/mid-auth.js +2 -5
- package/build/main.js +12 -15
- package/build/mock/tls-options.js +46 -44
- package/build/signup/routes/add.js +4 -4
- package/build/tests/admin-proto/signup.d.ts +1 -0
- package/build/tests/admin-proto/signup.js +235 -0
- package/build/tests/jasmine.d.ts +1 -0
- package/build/tests/jasmine.js +32 -0
- package/build/tests/libs-for-tests/3nstorage.d.ts +22 -0
- package/build/tests/libs-for-tests/3nstorage.js +123 -0
- package/build/tests/libs-for-tests/asmail.d.ts +22 -0
- package/build/tests/libs-for-tests/asmail.js +179 -0
- package/build/tests/libs-for-tests/assert.d.ts +1 -0
- package/build/tests/libs-for-tests/assert.js +26 -0
- package/build/tests/libs-for-tests/async-jasmine.d.ts +7 -0
- package/build/tests/libs-for-tests/async-jasmine.js +77 -0
- package/build/tests/libs-for-tests/bytes-equal.d.ts +1 -0
- package/build/tests/libs-for-tests/bytes-equal.js +34 -0
- package/build/tests/libs-for-tests/json-copy.d.ts +1 -0
- package/build/tests/libs-for-tests/json-copy.js +45 -0
- package/build/tests/libs-for-tests/json-equal.d.ts +4 -0
- package/build/tests/libs-for-tests/json-equal.js +67 -0
- package/build/tests/libs-for-tests/mailerid.d.ts +13 -0
- package/build/tests/libs-for-tests/mailerid.js +114 -0
- package/build/tests/libs-for-tests/pkl.d.ts +28 -0
- package/build/tests/libs-for-tests/pkl.js +89 -0
- package/build/tests/libs-for-tests/server-components/3nstorage.d.ts +20 -0
- package/build/tests/libs-for-tests/server-components/3nstorage.js +200 -0
- package/build/tests/libs-for-tests/server-components/admin.d.ts +6 -0
- package/build/tests/libs-for-tests/server-components/admin.js +43 -0
- package/build/tests/libs-for-tests/server-components/asmail.d.ts +16 -0
- package/build/tests/libs-for-tests/server-components/asmail.js +143 -0
- package/build/tests/libs-for-tests/server-components/component.d.ts +13 -0
- package/build/tests/libs-for-tests/server-components/component.js +77 -0
- package/build/tests/libs-for-tests/server-components/mailerid.d.ts +10 -0
- package/build/tests/libs-for-tests/server-components/mailerid.js +103 -0
- package/build/tests/libs-for-tests/server-runner.d.ts +15 -0
- package/build/tests/libs-for-tests/server-runner.js +69 -0
- package/build/tests/libs-for-tests/spec-assembly.d.ts +6 -0
- package/build/tests/libs-for-tests/spec-assembly.js +55 -0
- package/build/tests/libs-for-tests/ws-utils.d.ts +3 -0
- package/build/tests/libs-for-tests/ws-utils.js +59 -0
- package/build/tests/libs-for-tests/xhr-utils.d.ts +61 -0
- package/build/tests/libs-for-tests/xhr-utils.js +154 -0
- package/build/tests/protocols/3nstorage/owner/specs/archive-obj-ver.d.ts +2 -0
- package/build/tests/protocols/3nstorage/owner/specs/archive-obj-ver.js +84 -0
- package/build/tests/protocols/3nstorage/owner/specs/archive-root-ver.d.ts +2 -0
- package/build/tests/protocols/3nstorage/owner/specs/archive-root-ver.js +78 -0
- package/build/tests/protocols/3nstorage/owner/specs/delete-archive-obj-ver.d.ts +2 -0
- package/build/tests/protocols/3nstorage/owner/specs/delete-archive-obj-ver.js +83 -0
- package/build/tests/protocols/3nstorage/owner/specs/delete-archive-root-ver.d.ts +2 -0
- package/build/tests/protocols/3nstorage/owner/specs/delete-archive-root-ver.js +77 -0
- package/build/tests/protocols/3nstorage/owner/specs/delete-obj.d.ts +2 -0
- package/build/tests/protocols/3nstorage/owner/specs/delete-obj.js +75 -0
- package/build/tests/protocols/3nstorage/owner/specs/events.d.ts +2 -0
- package/build/tests/protocols/3nstorage/owner/specs/events.js +91 -0
- package/build/tests/protocols/3nstorage/owner/specs/get-current-obj.d.ts +2 -0
- package/build/tests/protocols/3nstorage/owner/specs/get-current-obj.js +269 -0
- package/build/tests/protocols/3nstorage/owner/specs/get-current-root.d.ts +2 -0
- package/build/tests/protocols/3nstorage/owner/specs/get-current-root.js +262 -0
- package/build/tests/protocols/3nstorage/owner/specs/get-obj-status.d.ts +2 -0
- package/build/tests/protocols/3nstorage/owner/specs/get-obj-status.js +79 -0
- package/build/tests/protocols/3nstorage/owner/specs/get-root-status.d.ts +2 -0
- package/build/tests/protocols/3nstorage/owner/specs/get-root-status.js +72 -0
- package/build/tests/protocols/3nstorage/owner/specs/put-current-obj.d.ts +2 -0
- package/build/tests/protocols/3nstorage/owner/specs/put-current-obj.js +287 -0
- package/build/tests/protocols/3nstorage/owner/specs/put-current-root.d.ts +2 -0
- package/build/tests/protocols/3nstorage/owner/specs/put-current-root.js +274 -0
- package/build/tests/protocols/3nstorage/owner/specs/trans-cancel-root.d.ts +2 -0
- package/build/tests/protocols/3nstorage/owner/specs/trans-cancel-root.js +73 -0
- package/build/tests/protocols/3nstorage/owner/specs/trans-cancel.d.ts +2 -0
- package/build/tests/protocols/3nstorage/owner/specs/trans-cancel.js +72 -0
- package/build/tests/protocols/3nstorage/owner/test-utils.d.ts +14 -0
- package/build/tests/protocols/3nstorage/owner/test-utils.js +54 -0
- package/build/tests/protocols/3nstorage/owner.d.ts +1 -0
- package/build/tests/protocols/3nstorage/owner.js +138 -0
- package/build/tests/protocols/asmail/config.d.ts +1 -0
- package/build/tests/protocols/asmail/config.js +117 -0
- package/build/tests/protocols/asmail/delivery/specs/finalize-delivery.d.ts +2 -0
- package/build/tests/protocols/asmail/delivery/specs/finalize-delivery.js +60 -0
- package/build/tests/protocols/asmail/delivery/specs/provide-recipient-pubkey.d.ts +2 -0
- package/build/tests/protocols/asmail/delivery/specs/provide-recipient-pubkey.js +68 -0
- package/build/tests/protocols/asmail/delivery/specs/put-metadata.d.ts +2 -0
- package/build/tests/protocols/asmail/delivery/specs/put-metadata.js +83 -0
- package/build/tests/protocols/asmail/delivery/specs/put-obj.d.ts +2 -0
- package/build/tests/protocols/asmail/delivery/specs/put-obj.js +123 -0
- package/build/tests/protocols/asmail/delivery/specs/restart-session.d.ts +2 -0
- package/build/tests/protocols/asmail/delivery/specs/restart-session.js +79 -0
- package/build/tests/protocols/asmail/delivery/specs/start-session.d.ts +2 -0
- package/build/tests/protocols/asmail/delivery/specs/start-session.js +64 -0
- package/build/tests/protocols/asmail/delivery/test-utils.d.ts +16 -0
- package/build/tests/protocols/asmail/delivery/test-utils.js +46 -0
- package/build/tests/protocols/asmail/delivery.d.ts +1 -0
- package/build/tests/protocols/asmail/delivery.js +46 -0
- package/build/tests/protocols/asmail/retrieval/specs/events.d.ts +2 -0
- package/build/tests/protocols/asmail/retrieval/specs/events.js +62 -0
- package/build/tests/protocols/asmail/retrieval/specs/get-message-meta.d.ts +2 -0
- package/build/tests/protocols/asmail/retrieval/specs/get-message-meta.js +70 -0
- package/build/tests/protocols/asmail/retrieval/specs/get-message-obj.d.ts +2 -0
- package/build/tests/protocols/asmail/retrieval/specs/get-message-obj.js +166 -0
- package/build/tests/protocols/asmail/retrieval/specs/list-messages.d.ts +2 -0
- package/build/tests/protocols/asmail/retrieval/specs/list-messages.js +96 -0
- package/build/tests/protocols/asmail/retrieval/specs/remove-message.d.ts +2 -0
- package/build/tests/protocols/asmail/retrieval/specs/remove-message.js +66 -0
- package/build/tests/protocols/asmail/retrieval/test-utils.d.ts +17 -0
- package/build/tests/protocols/asmail/retrieval/test-utils.js +46 -0
- package/build/tests/protocols/asmail/retrieval.d.ts +1 -0
- package/build/tests/protocols/asmail/retrieval.js +92 -0
- package/build/tests/protocols/mailerid.d.ts +1 -0
- package/build/tests/protocols/mailerid.js +210 -0
- package/build/tests/shared-checks/check-mid-login.d.ts +2 -0
- package/build/tests/shared-checks/check-mid-login.js +131 -0
- package/build/tests/shared-checks/requests.d.ts +20 -0
- package/build/tests/shared-checks/requests.js +123 -0
- package/package.json +1 -1
- package/packing/create-deb.sh +57 -0
- package/packing/deb/lib/systemd/system/3nweb.service +11 -0
- package/packing/deb/postinst +44 -0
- package/packing/deb/usr/share/doc/3nweb-server/conf-for-postinstall.yaml +19 -0
- package/packing/deb/usr/share/doc/3nweb-server/copyright +22 -0
- package/publish-task.sh +10 -0
- package/push-to-github.sh +105 -0
- package/ts-code/3nstorage/3nstorage-app.ts +99 -0
- package/ts-code/3nstorage/owner.ts +178 -0
- package/ts-code/3nstorage/resources/sessions.ts +37 -0
- package/ts-code/3nstorage/resources/store.ts +896 -0
- package/ts-code/3nstorage/resources/users.ts +258 -0
- package/ts-code/3nstorage/routes/owner/archive-obj-version.ts +73 -0
- package/ts-code/3nstorage/routes/owner/cancel-trans.ts +58 -0
- package/ts-code/3nstorage/routes/owner/delete-obj.ts +103 -0
- package/ts-code/3nstorage/routes/owner/get-archived-obj-ver.ts +111 -0
- package/ts-code/3nstorage/routes/owner/get-current-obj.ts +122 -0
- package/ts-code/3nstorage/routes/owner/get-obj-status.ts +55 -0
- package/ts-code/3nstorage/routes/owner/param-getter.ts +51 -0
- package/ts-code/3nstorage/routes/owner/param-setter.ts +50 -0
- package/ts-code/3nstorage/routes/owner/put-current-obj.ts +284 -0
- package/ts-code/3nstorage/routes/owner/session-params.ts +49 -0
- package/ts-code/3nstorage/shared.ts +43 -0
- package/ts-code/asmail/asmail-app.ts +91 -0
- package/ts-code/asmail/config.ts +96 -0
- package/ts-code/asmail/delivery.ts +94 -0
- package/ts-code/asmail/resources/delivery-sessions.ts +118 -0
- package/ts-code/asmail/resources/inbox.ts +696 -0
- package/ts-code/asmail/resources/recipients.ts +495 -0
- package/ts-code/asmail/resources/sessions.ts +37 -0
- package/ts-code/asmail/retrieval.ts +96 -0
- package/ts-code/asmail/routes/config/param-getter.ts +49 -0
- package/ts-code/asmail/routes/config/param-setter.ts +49 -0
- package/ts-code/asmail/routes/delivery/finalize-delivery.ts +50 -0
- package/ts-code/asmail/routes/delivery/pre-flight.ts +132 -0
- package/ts-code/asmail/routes/delivery/provide-recipient-pubkey.ts +58 -0
- package/ts-code/asmail/routes/delivery/put-metadata.ts +94 -0
- package/ts-code/asmail/routes/delivery/put-obj.ts +166 -0
- package/ts-code/asmail/routes/delivery/restart-session.ts +130 -0
- package/ts-code/asmail/routes/delivery/sender-authorization.ts +81 -0
- package/ts-code/asmail/routes/delivery/start-session.ts +151 -0
- package/ts-code/asmail/routes/retrieval/get-message-meta.ts +53 -0
- package/ts-code/asmail/routes/retrieval/get-message-obj.ts +109 -0
- package/ts-code/asmail/routes/retrieval/list-messages.ts +70 -0
- package/ts-code/asmail/routes/retrieval/remove-message.ts +47 -0
- package/ts-code/cli/index.ts +82 -0
- package/ts-code/cli/run-cmd.ts +81 -0
- package/ts-code/cli/show-sample-config.ts +78 -0
- package/ts-code/cli/signup-cmd.ts +229 -0
- package/ts-code/cli/user-cmd.ts +68 -0
- package/ts-code/cli/utils.ts +105 -0
- package/ts-code/config/default-confs.ts +22 -0
- package/ts-code/config/from-yaml.ts +35 -0
- package/ts-code/config/letsencrypt.ts +77 -0
- package/ts-code/config/signup.ts +137 -0
- package/ts-code/lib-common/admin-api/signup.ts +120 -0
- package/ts-code/lib-common/assert.ts +22 -0
- package/ts-code/lib-common/async-fs-node.ts +656 -0
- package/ts-code/lib-common/buffer-utils.ts +124 -0
- package/ts-code/lib-common/byte-streaming/common.ts +166 -0
- package/ts-code/lib-common/bytes-equal.ts +25 -0
- package/ts-code/lib-common/canonical-address.ts +92 -0
- package/ts-code/lib-common/exceptions/error.ts +44 -0
- package/ts-code/lib-common/exceptions/file.ts +84 -0
- package/ts-code/lib-common/exceptions/http.ts +69 -0
- package/ts-code/lib-common/ipc/generic-ipc.ts +750 -0
- package/ts-code/lib-common/ipc/ws-ipc.ts +117 -0
- package/ts-code/lib-common/json-equal.ts +55 -0
- package/ts-code/lib-common/json-utils.ts +130 -0
- package/ts-code/lib-common/jwkeys.ts +246 -0
- package/ts-code/lib-common/map-of-sets.ts +60 -0
- package/ts-code/lib-common/mid-sigs-NaCl-Ed.ts +677 -0
- package/ts-code/lib-common/objs-on-disk/file-layout.ts +480 -0
- package/ts-code/lib-common/objs-on-disk/obj-file.ts +325 -0
- package/ts-code/lib-common/objs-on-disk/utils.ts +201 -0
- package/ts-code/lib-common/objs-on-disk/v1-obj-file-format.ts +329 -0
- package/ts-code/lib-common/processes.ts +501 -0
- package/ts-code/lib-common/random-node.ts +79 -0
- package/ts-code/lib-common/service-api/3nstorage/owner.ts +559 -0
- package/ts-code/lib-common/service-api/3nstorage/root-route.ts +22 -0
- package/ts-code/lib-common/service-api/asmail/config.ts +144 -0
- package/ts-code/lib-common/service-api/asmail/delivery.ts +250 -0
- package/ts-code/lib-common/service-api/asmail/retrieval.ts +238 -0
- package/ts-code/lib-common/service-api/asmail/root-route.ts +22 -0
- package/ts-code/lib-common/service-api/ipc-api.ts +44 -0
- package/ts-code/lib-common/service-api/locker.ts +44 -0
- package/ts-code/lib-common/service-api/mailer-id/login.ts +80 -0
- package/ts-code/lib-common/service-api/mailer-id/provisioning.ts +64 -0
- package/ts-code/lib-common/service-api/mailer-id/root-route.ts +25 -0
- package/ts-code/lib-common/service-api/pub-key-login.ts +75 -0
- package/ts-code/lib-common/service-api/web-socket-base.ts +87 -0
- package/ts-code/lib-common/session-encryptor.ts +54 -0
- package/ts-code/lib-common/time-window-cache.ts +74 -0
- package/ts-code/lib-common/transferable.d.ts +30 -0
- package/ts-code/lib-server/conf-util.ts +35 -0
- package/ts-code/lib-server/mid-access.ts +45 -0
- package/ts-code/lib-server/middleware/body-parsers.ts +248 -0
- package/ts-code/lib-server/middleware/error-handler.ts +79 -0
- package/ts-code/lib-server/pkl-access.ts +46 -0
- package/ts-code/lib-server/resources/dns.ts +151 -0
- package/ts-code/lib-server/resources/mailerid-authorizer.ts +115 -0
- package/ts-code/lib-server/resources/mem-backed-sessions-factory.ts +132 -0
- package/ts-code/lib-server/resources/server-data-folders.ts +160 -0
- package/ts-code/lib-server/resources/server-key-for-pkl-challenge.ts +41 -0
- package/ts-code/lib-server/resources/sessions.ts +232 -0
- package/ts-code/lib-server/resources/user-files.ts +147 -0
- package/ts-code/lib-server/routes/pub-key-login/complete-exchange.ts +63 -0
- package/ts-code/lib-server/routes/pub-key-login/start-exchange.ts +189 -0
- package/ts-code/lib-server/routes/sessions/close.ts +27 -0
- package/ts-code/lib-server/routes/sessions/mid-auth.ts +77 -0
- package/ts-code/lib-server/routes/sessions/start.ts +116 -0
- package/ts-code/lib-server/web-sockets/app.ts +339 -0
- package/ts-code/lib-server/web-sockets/server-events.ts +63 -0
- package/ts-code/lib.ts +29 -0
- package/ts-code/locker/locker-app.ts +60 -0
- package/ts-code/locker/resources/lockers.ts +17 -0
- package/ts-code/locker/resources/sessions.ts +37 -0
- package/ts-code/locker/routes/create-locker.ts +47 -0
- package/ts-code/mailerId/mailerId-app.ts +107 -0
- package/ts-code/mailerId/resources/certifier.ts +181 -0
- package/ts-code/mailerId/resources/sessions.ts +44 -0
- package/ts-code/mailerId/resources/users.ts +88 -0
- package/ts-code/mailerId/routes/certify.ts +68 -0
- package/ts-code/main.ts +304 -0
- package/ts-code/mock/dns.ts +106 -0
- package/ts-code/mock/mock-as-child-proc.ts +130 -0
- package/ts-code/mock/node-child-ipc.ts +69 -0
- package/ts-code/mock/run-in-proc.ts +111 -0
- package/ts-code/mock/tls-options.ts +73 -0
- package/ts-code/services.ts +138 -0
- package/ts-code/signup/resources/users.ts +429 -0
- package/ts-code/signup/routes/add.ts +65 -0
- package/ts-code/signup/routes/get-available-addresses.ts +49 -0
- package/ts-code/signup/routes/get-available-domains.ts +45 -0
- package/ts-code/signup/signup-app.ts +54 -0
- package/ts-code/signup/signup-tokens.ts +148 -0
- package/ts-code/tests/admin-proto/signup.ts +277 -0
- package/ts-code/tests/jasmine.ts +37 -0
- package/ts-code/tests/libs-for-tests/3nstorage.ts +144 -0
- package/ts-code/tests/libs-for-tests/asmail.ts +220 -0
- package/ts-code/tests/libs-for-tests/assert.ts +22 -0
- package/ts-code/tests/libs-for-tests/async-jasmine.ts +89 -0
- package/ts-code/tests/libs-for-tests/bytes-equal.ts +25 -0
- package/ts-code/tests/libs-for-tests/json-copy.ts +38 -0
- package/ts-code/tests/libs-for-tests/json-equal.ts +55 -0
- package/ts-code/tests/libs-for-tests/mailerid.ts +123 -0
- package/ts-code/tests/libs-for-tests/pkl.ts +127 -0
- package/ts-code/tests/libs-for-tests/server-components/3nstorage.ts +206 -0
- package/ts-code/tests/libs-for-tests/server-components/admin.ts +49 -0
- package/ts-code/tests/libs-for-tests/server-components/asmail.ts +152 -0
- package/ts-code/tests/libs-for-tests/server-components/component.ts +90 -0
- package/ts-code/tests/libs-for-tests/server-components/mailerid.ts +114 -0
- package/ts-code/tests/libs-for-tests/server-runner.ts +82 -0
- package/ts-code/tests/libs-for-tests/spec-assembly.ts +60 -0
- package/ts-code/tests/libs-for-tests/ws-utils.ts +61 -0
- package/ts-code/tests/libs-for-tests/xhr-utils.ts +179 -0
- package/ts-code/tests/protocols/3nstorage/owner/specs/archive-obj-ver.ts +100 -0
- package/ts-code/tests/protocols/3nstorage/owner/specs/archive-root-ver.ts +91 -0
- package/ts-code/tests/protocols/3nstorage/owner/specs/delete-archive-obj-ver.ts +99 -0
- package/ts-code/tests/protocols/3nstorage/owner/specs/delete-archive-root-ver.ts +90 -0
- package/ts-code/tests/protocols/3nstorage/owner/specs/delete-obj.ts +84 -0
- package/ts-code/tests/protocols/3nstorage/owner/specs/events.ts +125 -0
- package/ts-code/tests/protocols/3nstorage/owner/specs/get-current-obj.ts +298 -0
- package/ts-code/tests/protocols/3nstorage/owner/specs/get-current-root.ts +290 -0
- package/ts-code/tests/protocols/3nstorage/owner/specs/get-obj-status.ts +88 -0
- package/ts-code/tests/protocols/3nstorage/owner/specs/get-root-status.ts +80 -0
- package/ts-code/tests/protocols/3nstorage/owner/specs/put-current-obj.ts +366 -0
- package/ts-code/tests/protocols/3nstorage/owner/specs/put-current-root.ts +329 -0
- package/ts-code/tests/protocols/3nstorage/owner/specs/trans-cancel-root.ts +86 -0
- package/ts-code/tests/protocols/3nstorage/owner/specs/trans-cancel.ts +86 -0
- package/ts-code/tests/protocols/3nstorage/owner/test-utils.ts +72 -0
- package/ts-code/tests/protocols/3nstorage/owner.ts +198 -0
- package/ts-code/tests/protocols/asmail/config.ts +172 -0
- package/ts-code/tests/protocols/asmail/delivery/specs/finalize-delivery.ts +69 -0
- package/ts-code/tests/protocols/asmail/delivery/specs/provide-recipient-pubkey.ts +88 -0
- package/ts-code/tests/protocols/asmail/delivery/specs/put-metadata.ts +102 -0
- package/ts-code/tests/protocols/asmail/delivery/specs/put-obj.ts +156 -0
- package/ts-code/tests/protocols/asmail/delivery/specs/restart-session.ts +97 -0
- package/ts-code/tests/protocols/asmail/delivery/specs/start-session.ts +79 -0
- package/ts-code/tests/protocols/asmail/delivery/test-utils.ts +64 -0
- package/ts-code/tests/protocols/asmail/delivery.ts +56 -0
- package/ts-code/tests/protocols/asmail/retrieval/specs/events.ts +78 -0
- package/ts-code/tests/protocols/asmail/retrieval/specs/get-message-meta.ts +80 -0
- package/ts-code/tests/protocols/asmail/retrieval/specs/get-message-obj.ts +197 -0
- package/ts-code/tests/protocols/asmail/retrieval/specs/list-messages.ts +110 -0
- package/ts-code/tests/protocols/asmail/retrieval/specs/remove-message.ts +74 -0
- package/ts-code/tests/protocols/asmail/retrieval/test-utils.ts +60 -0
- package/ts-code/tests/protocols/asmail/retrieval.ts +115 -0
- package/ts-code/tests/protocols/mailerid.ts +271 -0
- package/ts-code/tests/shared-checks/check-mid-login.ts +164 -0
- package/ts-code/tests/shared-checks/requests.ts +135 -0
- package/ts-code/tsconfig.json +11 -0
- package/ts-code/web3n.d.ts +1068 -0
|
@@ -0,0 +1,696 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (C) 2015 - 2017, 2019 - 2020, 2025 3NSoft Inc.
|
|
3
|
+
|
|
4
|
+
This program is free software: you can redistribute it and/or modify it under
|
|
5
|
+
the terms of the GNU General Public License as published by the Free Software
|
|
6
|
+
Foundation, either version 3 of the License, or (at your option) any later
|
|
7
|
+
version.
|
|
8
|
+
|
|
9
|
+
This program is distributed in the hope that it will be useful, but
|
|
10
|
+
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
12
|
+
See the GNU General Public License for more details.
|
|
13
|
+
|
|
14
|
+
You should have received a copy of the GNU General Public License along with
|
|
15
|
+
this program. If not, see <http://www.gnu.org/licenses/>.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Inbox files are laid out on disk in the following way:
|
|
20
|
+
* (a) store is just a folder with stuff inside;
|
|
21
|
+
* (b) main store folder contains following folders:
|
|
22
|
+
* (b.1) messages - is a folder for message folders,
|
|
23
|
+
* (b.2) delivery - is a folder for messages, that are in a process of
|
|
24
|
+
* being delivered; complete messages are moved to
|
|
25
|
+
* 'messages' folder.
|
|
26
|
+
* (b.3) params - is a place for information files about this mail box;
|
|
27
|
+
* (c) message folder's name is message's id. Each message folder contains:
|
|
28
|
+
* (c.1) meta - is a file with plain-text JSON-form metadata for a message.
|
|
29
|
+
* (c.2) objects - is a folder with all object files, that are part of the
|
|
30
|
+
* message.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import * as fs from '../../lib-common/async-fs-node';
|
|
34
|
+
import { Readable } from 'stream';
|
|
35
|
+
import { isLikeSignedKeyCert } from '../../lib-common/jwkeys';
|
|
36
|
+
import * as random from '../../lib-common/random-node';
|
|
37
|
+
import * as deliveryApi from '../../lib-common/service-api/asmail/delivery';
|
|
38
|
+
import * as configApi from '../../lib-common/service-api/asmail/config';
|
|
39
|
+
import * as retrievalApi from '../../lib-common/service-api/asmail/retrieval';
|
|
40
|
+
import { UserFiles, SC as ufSC, ObjReader } from '../../lib-server/resources/user-files';
|
|
41
|
+
import { NamedProcs } from '../../lib-common/processes';
|
|
42
|
+
import { TimeWindowCache } from '../../lib-common/time-window-cache';
|
|
43
|
+
import { ObjVersionFile } from '../../lib-common/objs-on-disk/obj-file';
|
|
44
|
+
import { join } from 'path';
|
|
45
|
+
import { errWithCause } from '../../lib-common/exceptions/error';
|
|
46
|
+
import { chunksInOrderedStream, streamToObjFile, makeNoBaseObjPipe } from '../../lib-common/objs-on-disk/utils';
|
|
47
|
+
|
|
48
|
+
export { ObjPipe, ObjReader } from '../../lib-server/resources/user-files';
|
|
49
|
+
|
|
50
|
+
type InitPubKey = configApi.p.initPubKey.Certs;
|
|
51
|
+
type AnonSenderPolicy = configApi.p.anonSenderPolicy.Policy;
|
|
52
|
+
export type AuthSenderPolicy = configApi.p.authSenderPolicy.Policy;
|
|
53
|
+
type Whitelist = configApi.p.authSenderWhitelist.List;
|
|
54
|
+
type Blacklist = configApi.p.authSenderBlacklist.List;
|
|
55
|
+
type AuthSenderInvites = configApi.p.authSenderInvites.List;
|
|
56
|
+
type AnonSenderInvites = configApi.p.anonSenderInvites.List;
|
|
57
|
+
|
|
58
|
+
type MsgMeta = retrievalApi.MsgMeta;
|
|
59
|
+
export type MsgEvents = retrievalApi.msgMainObjRecieved.Event |
|
|
60
|
+
retrievalApi.msgRecievedCompletely.Event;
|
|
61
|
+
|
|
62
|
+
export type MailEventsSink = (
|
|
63
|
+
userId: string, channel: string, event: MsgEvents
|
|
64
|
+
) => void;
|
|
65
|
+
|
|
66
|
+
export const SC = {
|
|
67
|
+
OBJ_EXIST: 'obj-already-exist',
|
|
68
|
+
USER_UNKNOWN: ufSC.USER_UNKNOWN,
|
|
69
|
+
MSG_UNKNOWN: 'msg-unknown',
|
|
70
|
+
OBJ_UNKNOWN: 'obj-unknown',
|
|
71
|
+
WRONG_OBJ_STATE: 'wrong-obj-state',
|
|
72
|
+
OBJ_FILE_INCOMPLETE: 'obj-file-incomplete'
|
|
73
|
+
};
|
|
74
|
+
Object.freeze(SC);
|
|
75
|
+
|
|
76
|
+
const META_FILE = 'meta.json';
|
|
77
|
+
|
|
78
|
+
const MSG_ID_LEN = 32;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* This returns a promise, resolvable to generated msg id, when folder for a
|
|
82
|
+
* message is created in the delivery folder.
|
|
83
|
+
* @param delivPath
|
|
84
|
+
* @param msgsFolder is an additional folder, checked against id-collision
|
|
85
|
+
*/
|
|
86
|
+
async function genMsgIdAndMakeFolder(
|
|
87
|
+
delivPath: string, msgsFolder: string
|
|
88
|
+
): Promise<string> {
|
|
89
|
+
const msgId = await random.stringOfB64UrlSafeChars(MSG_ID_LEN);
|
|
90
|
+
// make msg folder among deliveries
|
|
91
|
+
try {
|
|
92
|
+
await fs.mkdir(join(delivPath, msgId));
|
|
93
|
+
} catch (exc) {
|
|
94
|
+
if ((<fs.FileException> exc).alreadyExists) {
|
|
95
|
+
return genMsgIdAndMakeFolder(delivPath, msgsFolder);
|
|
96
|
+
} else { throw exc; }
|
|
97
|
+
}
|
|
98
|
+
// ensure that msgId does not belong to any existing message
|
|
99
|
+
try {
|
|
100
|
+
await fs.stat(join(msgsFolder, msgId));
|
|
101
|
+
await fs.rmdir(join(delivPath, msgId));
|
|
102
|
+
return genMsgIdAndMakeFolder(delivPath, msgsFolder);
|
|
103
|
+
} catch (exc) {}
|
|
104
|
+
return msgId;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface InboxParams {
|
|
108
|
+
"pubkey": InitPubKey|null;
|
|
109
|
+
"anonymous/policy": AnonSenderPolicy;
|
|
110
|
+
"anonymous/invites": AnonSenderInvites;
|
|
111
|
+
"authenticated/policy": AuthSenderPolicy;
|
|
112
|
+
"authenticated/blacklist": Blacklist;
|
|
113
|
+
"authenticated/whitelist": Whitelist;
|
|
114
|
+
"authenticated/invites": AuthSenderInvites;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
export class Inbox extends UserFiles<InboxParams> {
|
|
119
|
+
|
|
120
|
+
private metas = new MsgMetas(
|
|
121
|
+
5*60*1000, join(this.path, 'delivery'), join(this.path, 'messages'));
|
|
122
|
+
|
|
123
|
+
private objFiles = new ObjFiles(
|
|
124
|
+
5*60*1000, this.metas.deliveryFolder, this.metas.readyMsgsFolder);
|
|
125
|
+
|
|
126
|
+
private mailEventsSink: MailEventsSink;
|
|
127
|
+
|
|
128
|
+
constructor(
|
|
129
|
+
userId: string, path: string, mailEventsSink: MailEventsSink,
|
|
130
|
+
writeBufferSize?: string|number, readBufferSize?: string|number
|
|
131
|
+
) {
|
|
132
|
+
super(userId, path, writeBufferSize, readBufferSize);
|
|
133
|
+
this.mailEventsSink = mailEventsSink;
|
|
134
|
+
Object.freeze(this);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
static async make(
|
|
138
|
+
userFolder: string, userId: string, mailEventsSink: MailEventsSink,
|
|
139
|
+
writeBufferSize?: string|number, readBufferSize?: string|number
|
|
140
|
+
): Promise<Inbox> {
|
|
141
|
+
const path = join(userFolder, 'mail');
|
|
142
|
+
const inbox = new Inbox(
|
|
143
|
+
userId, path, mailEventsSink, writeBufferSize, readBufferSize
|
|
144
|
+
);
|
|
145
|
+
await inbox.ensureUserExistsOnDisk();
|
|
146
|
+
return inbox;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* @return a promise, resolvable to number bytes used by this inbox.
|
|
151
|
+
*/
|
|
152
|
+
async usedSpace(): Promise<number> {
|
|
153
|
+
// XXX need to use space-tracker service!
|
|
154
|
+
// For now we return zero.
|
|
155
|
+
return 0;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* @return a promise, resolvable to free space in bytes.
|
|
160
|
+
*/
|
|
161
|
+
async freeSpace(): Promise<number> {
|
|
162
|
+
// XXX need to use space-tracker service!
|
|
163
|
+
const usedSpace = await this.usedSpace();
|
|
164
|
+
const quota = await this.getSpaceQuota();
|
|
165
|
+
return Math.max(0, quota - usedSpace);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* This returns a promise, resolvable to message id, when a folder for new
|
|
170
|
+
* message has been created.
|
|
171
|
+
* @param extMeta is json object with message's meta info directly from
|
|
172
|
+
* sender.
|
|
173
|
+
* @param authSender is an address of sender, if such was authenticated.
|
|
174
|
+
* @param invite is an invitation token, if any were used.
|
|
175
|
+
*/
|
|
176
|
+
async recordMsgMeta(
|
|
177
|
+
extMeta: deliveryApi.msgMeta.Request, authSender: string|undefined,
|
|
178
|
+
invite: string|undefined, maxMsgLength: number
|
|
179
|
+
): Promise<string> {
|
|
180
|
+
const msgId = await genMsgIdAndMakeFolder(
|
|
181
|
+
this.metas.deliveryFolder, this.metas.readyMsgsFolder);
|
|
182
|
+
const meta: MsgMeta = {
|
|
183
|
+
extMeta, authSender, invite, maxMsgLength,
|
|
184
|
+
recipient: this.userId,
|
|
185
|
+
deliveryStart: Date.now(),
|
|
186
|
+
objs: {}
|
|
187
|
+
};
|
|
188
|
+
await this.metas.set(msgId, meta);
|
|
189
|
+
return msgId;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* This returns a promise, resolvable to message metadata from disk, when it
|
|
194
|
+
* as been found on the disk.
|
|
195
|
+
* Rejected promise may pass a string error code from SC.
|
|
196
|
+
* @param msgId
|
|
197
|
+
* @param completeMsg flag, true for complete messages, and false for
|
|
198
|
+
* incomplete (in-delivery) messages.
|
|
199
|
+
*/
|
|
200
|
+
async getMsgMeta(msgId: string, completeMsg: boolean): Promise<MsgMeta> {
|
|
201
|
+
return this.metas.get(msgId, completeMsg);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
async startSavingObj(
|
|
205
|
+
msgId: string, objId: string, bytes: Readable, bytesLen: number,
|
|
206
|
+
opts: deliveryApi.PutObjFirstQueryOpts
|
|
207
|
+
): Promise<void> {
|
|
208
|
+
// check meta
|
|
209
|
+
const meta = await this.metas.get(msgId, false);
|
|
210
|
+
if (meta.extMeta.objIds.indexOf(objId) < 0) { throw SC.OBJ_UNKNOWN; }
|
|
211
|
+
if (meta.objs[objId]) { throw SC.WRONG_OBJ_STATE; }
|
|
212
|
+
|
|
213
|
+
const file = await this.objFiles.forNewFile(msgId, objId);
|
|
214
|
+
const chunks = chunksInOrderedStream(bytesLen, opts.header, 0);
|
|
215
|
+
await streamToObjFile(file, chunks, bytes, this.fileWritingBufferSize);
|
|
216
|
+
|
|
217
|
+
// set obj status in meta
|
|
218
|
+
meta.objs[objId] = {
|
|
219
|
+
size: {
|
|
220
|
+
header: opts.header,
|
|
221
|
+
segments: bytesLen - opts.header
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
if (opts.last) {
|
|
225
|
+
if (file.isFileComplete()) {
|
|
226
|
+
meta.objs[objId].completed = true;
|
|
227
|
+
} else {
|
|
228
|
+
await this.metas.set(msgId, meta);
|
|
229
|
+
throw SC.OBJ_FILE_INCOMPLETE;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
await this.metas.set(msgId, meta);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
async continueSavingObj(
|
|
236
|
+
msgId: string, objId: string, bytes: Readable, bytesLen: number,
|
|
237
|
+
opts: deliveryApi.PutObjSecondQueryOpts
|
|
238
|
+
): Promise<void> {
|
|
239
|
+
// check obj status
|
|
240
|
+
const meta = await this.metas.get(msgId, false);
|
|
241
|
+
const objStatus = meta.objs[objId];
|
|
242
|
+
if (objStatus) {
|
|
243
|
+
if (objStatus.completed) { throw SC.WRONG_OBJ_STATE; }
|
|
244
|
+
} else {
|
|
245
|
+
if (meta.extMeta.objIds.indexOf(objId) < 0) { throw SC.OBJ_UNKNOWN; }
|
|
246
|
+
else { throw SC.WRONG_OBJ_STATE; }
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const file = await this.objFiles.forExistingFile(msgId, objId, true);
|
|
250
|
+
const chunks = chunksInOrderedStream(bytesLen, undefined, opts.ofs);
|
|
251
|
+
await streamToObjFile(file, chunks, bytes, this.fileWritingBufferSize);
|
|
252
|
+
|
|
253
|
+
// update meta
|
|
254
|
+
objStatus.size.segments! += bytesLen;
|
|
255
|
+
if (opts.last) {
|
|
256
|
+
if (file.isFileComplete()) {
|
|
257
|
+
objStatus.completed = true;
|
|
258
|
+
} else {
|
|
259
|
+
await this.metas.set(msgId, meta);
|
|
260
|
+
throw SC.OBJ_FILE_INCOMPLETE;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
await this.metas.set(msgId, meta);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* This returns a promise, resolvable, when a message has been moved from
|
|
268
|
+
* delivery to messages storing folder.
|
|
269
|
+
* Rejected promise may pass string error code from SC.
|
|
270
|
+
* @param msgId
|
|
271
|
+
*/
|
|
272
|
+
async completeMsgDelivery(msgId: string): Promise<void> {
|
|
273
|
+
// indicate completion in meta
|
|
274
|
+
const meta = await this.metas.get(msgId, false);
|
|
275
|
+
if (!this.areAllMsgObjsComplete(msgId, meta)) {
|
|
276
|
+
throw SC.OBJ_FILE_INCOMPLETE;
|
|
277
|
+
}
|
|
278
|
+
meta.deliveryCompletion = Date.now();
|
|
279
|
+
await this.metas.set(msgId, meta);
|
|
280
|
+
|
|
281
|
+
// move message folder to a place with completed messages
|
|
282
|
+
const srcFolder = join(this.metas.deliveryFolder, msgId);
|
|
283
|
+
const dstFolder = join(this.metas.readyMsgsFolder, msgId);
|
|
284
|
+
await fs.rename(srcFolder, dstFolder);
|
|
285
|
+
this.objFiles.changeToReadingPathsInMsg(msgId);
|
|
286
|
+
|
|
287
|
+
// raise event about completion of receiving a message
|
|
288
|
+
this.mailEventsSink(this.userId,
|
|
289
|
+
retrievalApi.msgRecievedCompletely.EVENT_NAME,
|
|
290
|
+
{ msgId });
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
private areAllMsgObjsComplete(
|
|
294
|
+
msgId: string, meta: retrievalApi.MsgMeta
|
|
295
|
+
): boolean {
|
|
296
|
+
for (const status of Object.values(meta.objs)) {
|
|
297
|
+
if (!status.completed) { return false; }
|
|
298
|
+
}
|
|
299
|
+
return true;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* @param fromTS
|
|
304
|
+
* @param toTS
|
|
305
|
+
* @return a promise, resolvable to a list of available message ids.
|
|
306
|
+
*/
|
|
307
|
+
async getMsgIds(fromTS: number|undefined, toTS: number|undefined): Promise<retrievalApi.listMsgs.Reply> {
|
|
308
|
+
// XXX this isn't efficient, and needs sqlite-powered index
|
|
309
|
+
const lst = await fs.readdir(this.metas.readyMsgsFolder);
|
|
310
|
+
if ((fromTS === undefined) && (toTS === undefined)) {
|
|
311
|
+
return lst;
|
|
312
|
+
}
|
|
313
|
+
const filteredLst: string[] = [];
|
|
314
|
+
for (const msgId of lst) {
|
|
315
|
+
try {
|
|
316
|
+
const { deliveryStart } = await this.metas.get(msgId, true);
|
|
317
|
+
if (fromTS && (deliveryStart < fromTS)) {
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
if (toTS && (toTS < deliveryStart)) {
|
|
321
|
+
continue;
|
|
322
|
+
}
|
|
323
|
+
filteredLst.push(msgId);
|
|
324
|
+
} catch (exc) {}
|
|
325
|
+
}
|
|
326
|
+
return filteredLst;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* This method returns parameters of an incomplete message, identified
|
|
331
|
+
* by a given id.
|
|
332
|
+
* @param msgId
|
|
333
|
+
*/
|
|
334
|
+
async getIncompleteMsgParams(
|
|
335
|
+
msgId: string
|
|
336
|
+
): Promise<{ maxMsgLength: number; currentMsgLength: number; }> {
|
|
337
|
+
const msgMeta = await this.metas.get(msgId, false);
|
|
338
|
+
let currentMsgLength = 0;
|
|
339
|
+
for (const obj of Object.values(msgMeta.objs)) {
|
|
340
|
+
currentMsgLength += obj.size.header + obj.size.segments!;
|
|
341
|
+
}
|
|
342
|
+
const maxMsgLength = msgMeta.maxMsgLength;
|
|
343
|
+
return { maxMsgLength, currentMsgLength };
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* This method removes message folder from the disk.
|
|
348
|
+
* @param msgId is an id of a message, that needs to be removed.
|
|
349
|
+
* @return promise, resolvable when a message folder is removed from
|
|
350
|
+
* the disk.
|
|
351
|
+
* Rejected promise may pass string error code from SC.
|
|
352
|
+
*/
|
|
353
|
+
async rmMsg(msgId: string): Promise<void> {
|
|
354
|
+
this.metas.uncache(msgId);
|
|
355
|
+
this.objFiles.uncache(msgId);
|
|
356
|
+
try {
|
|
357
|
+
const msgPath = join(this.metas.readyMsgsFolder, msgId);
|
|
358
|
+
const rmPath = `${msgPath}~remove`;
|
|
359
|
+
await fs.rename(msgPath, rmPath);
|
|
360
|
+
await fs.rmDirWithContent(rmPath);
|
|
361
|
+
} catch (exc) {
|
|
362
|
+
if ((exc as fs.FileException).notFound) {
|
|
363
|
+
throw SC.MSG_UNKNOWN;
|
|
364
|
+
}
|
|
365
|
+
throw exc;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* This method returns promise that resolves to obj reader.
|
|
371
|
+
* @param msgId
|
|
372
|
+
* @param objId
|
|
373
|
+
* @param header is a boolean flag that says if header bytes should be
|
|
374
|
+
* read
|
|
375
|
+
* @param segsOffset indicates offset from which segment bytes should be
|
|
376
|
+
* read
|
|
377
|
+
* @param segsLimit
|
|
378
|
+
*/
|
|
379
|
+
async getObj(
|
|
380
|
+
msgId: string, objId: string,
|
|
381
|
+
header: boolean, segsOfs: number, segsLimit: number|undefined
|
|
382
|
+
): Promise<ObjReader> {
|
|
383
|
+
const file = await this.objFiles.forExistingFile(msgId, objId);
|
|
384
|
+
|
|
385
|
+
// find total segments length
|
|
386
|
+
const segsLen = file.getTotalSegsLen();
|
|
387
|
+
|
|
388
|
+
// contain boundary parameters offsetIntoSegs and len for segment bytes
|
|
389
|
+
if (segsLen < segsOfs) {
|
|
390
|
+
segsOfs = segsLen;
|
|
391
|
+
}
|
|
392
|
+
let segBytesToRead: number;
|
|
393
|
+
if (segsLimit === undefined) {
|
|
394
|
+
segBytesToRead = segsLen - segsOfs;
|
|
395
|
+
} else if ((segsOfs+segsLimit) >= segsLen) {
|
|
396
|
+
segBytesToRead = segsLen - segsOfs;
|
|
397
|
+
} else {
|
|
398
|
+
segBytesToRead = segsLimit;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// construct reader
|
|
402
|
+
let reader: ObjReader;
|
|
403
|
+
if (header) {
|
|
404
|
+
const headerLen = file.getHeaderLen()!;
|
|
405
|
+
reader = {
|
|
406
|
+
len: (segBytesToRead + headerLen),
|
|
407
|
+
segsLen,
|
|
408
|
+
headerLen,
|
|
409
|
+
pipe: makeNoBaseObjPipe(file, true, segsOfs, segBytesToRead)
|
|
410
|
+
};
|
|
411
|
+
} else {
|
|
412
|
+
reader = {
|
|
413
|
+
len: segBytesToRead,
|
|
414
|
+
segsLen,
|
|
415
|
+
pipe: makeNoBaseObjPipe(file, false, segsOfs, segBytesToRead)
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
Object.freeze(reader);
|
|
419
|
+
|
|
420
|
+
return reader;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* @param initKeyCerts
|
|
425
|
+
* @return a promise, resolvable to true, when certs are set, or
|
|
426
|
+
* resolvable to false, when given certs do not pass sanitization.
|
|
427
|
+
*/
|
|
428
|
+
async setPubKey(initKeyCerts: InitPubKey|null): Promise<boolean> {
|
|
429
|
+
if ((initKeyCerts === null) || isValidIntroPKeyCerts(initKeyCerts)) {
|
|
430
|
+
await this.setParam('pubkey', initKeyCerts);
|
|
431
|
+
return true;
|
|
432
|
+
} else {
|
|
433
|
+
return false;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
async setAnonSenderPolicy(policy: AnonSenderPolicy): Promise<boolean> {
|
|
438
|
+
if (isValidAnonSenderPolicy(policy)) {
|
|
439
|
+
await this.setParam('anonymous/policy', policy);
|
|
440
|
+
return true;
|
|
441
|
+
} else {
|
|
442
|
+
return false;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
async setAnonSenderInvites(invites: AnonSenderInvites): Promise<boolean> {
|
|
447
|
+
if (isValidListWithMsgMaxSizes(invites)) {
|
|
448
|
+
await this.setParam('anonymous/invites', invites);
|
|
449
|
+
return true;
|
|
450
|
+
} else {
|
|
451
|
+
return false;
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
async setAuthSenderPolicy(policy: AuthSenderPolicy): Promise<boolean> {
|
|
456
|
+
if (isValidAuthSenderPolicy(policy)) {
|
|
457
|
+
await this.setParam('authenticated/policy', policy);
|
|
458
|
+
return true;
|
|
459
|
+
} else {
|
|
460
|
+
return false;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
async setAuthSenderBlacklist(lst: Blacklist): Promise<boolean> {
|
|
465
|
+
if (isValidBlacklist(lst)) {
|
|
466
|
+
await this.setParam('authenticated/blacklist', lst);
|
|
467
|
+
return true;
|
|
468
|
+
} else {
|
|
469
|
+
return false;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
async setAuthSenderWhitelist(lst: Whitelist): Promise<boolean> {
|
|
474
|
+
if (isValidListWithMsgMaxSizes(lst)) {
|
|
475
|
+
await this.setParam('authenticated/whitelist', lst);
|
|
476
|
+
return true;
|
|
477
|
+
} else {
|
|
478
|
+
return false;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
async setAuthSenderInvites(invites: AuthSenderInvites): Promise<boolean> {
|
|
483
|
+
if (isValidListWithMsgMaxSizes(invites)) {
|
|
484
|
+
await this.setParam('authenticated/invites', invites);
|
|
485
|
+
return true;
|
|
486
|
+
} else {
|
|
487
|
+
return false;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
}
|
|
492
|
+
Object.freeze(Inbox.prototype);
|
|
493
|
+
Object.freeze(Inbox);
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
function isValidIntroPKeyCerts(pkeyCerts: InitPubKey): boolean {
|
|
497
|
+
return (
|
|
498
|
+
(typeof pkeyCerts === 'object') && !!pkeyCerts &&
|
|
499
|
+
isLikeSignedKeyCert(pkeyCerts.pkeyCert) &&
|
|
500
|
+
isLikeSignedKeyCert(pkeyCerts.userCert) &&
|
|
501
|
+
isLikeSignedKeyCert(pkeyCerts.provCert)
|
|
502
|
+
);
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
function isValidAnonSenderPolicy(policy: AnonSenderPolicy): boolean {
|
|
506
|
+
return (
|
|
507
|
+
('object' === typeof policy) && !!policy &&
|
|
508
|
+
('boolean' === typeof policy.accept) &&
|
|
509
|
+
('boolean' === typeof policy.acceptWithInvitesOnly) &&
|
|
510
|
+
('number' === typeof policy.defaultMsgSize) &&
|
|
511
|
+
(policy.defaultMsgSize > 500)
|
|
512
|
+
);
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
function isValidAuthSenderPolicy(policy: AuthSenderPolicy): boolean {
|
|
516
|
+
return (
|
|
517
|
+
('object' === typeof policy) && !!policy &&
|
|
518
|
+
('boolean' === typeof policy.applyBlackList) &&
|
|
519
|
+
('boolean' === typeof policy.acceptFromWhiteListOnly) &&
|
|
520
|
+
('boolean' === typeof policy.acceptWithInvitesOnly) &&
|
|
521
|
+
('number' === typeof policy.defaultMsgSize) &&
|
|
522
|
+
(policy.defaultMsgSize > 500)
|
|
523
|
+
);
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
function isValidListWithMsgMaxSizes(
|
|
527
|
+
lst: AuthSenderInvites|AnonSenderInvites|Whitelist
|
|
528
|
+
): boolean {
|
|
529
|
+
const isOK = ('object' === typeof lst) && !!lst;
|
|
530
|
+
if (!isOK) { return false; }
|
|
531
|
+
for (const inviteOrAddr in lst) {
|
|
532
|
+
const msgMaxSize = lst[inviteOrAddr];
|
|
533
|
+
const isOK = ('number' === typeof msgMaxSize) && (msgMaxSize > 500);
|
|
534
|
+
if (!isOK) { return false; }
|
|
535
|
+
}
|
|
536
|
+
return true;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
function isValidBlacklist(lst: Blacklist): boolean {
|
|
540
|
+
return ('object' === typeof lst) && !!lst;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
|
|
544
|
+
class ObjFiles {
|
|
545
|
+
|
|
546
|
+
private cache: TimeWindowCache<string, Map<string, ObjVersionFile>>;
|
|
547
|
+
|
|
548
|
+
constructor(
|
|
549
|
+
cachePeriodMillis: number,
|
|
550
|
+
public deliveryFolder: string,
|
|
551
|
+
public readyMsgsFolder: string
|
|
552
|
+
) {
|
|
553
|
+
this.cache = new TimeWindowCache(cachePeriodMillis);
|
|
554
|
+
Object.freeze(this);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
private getCached(msgId: string, objId: string): ObjVersionFile|undefined {
|
|
558
|
+
const msgObjs = this.cache.get(msgId);
|
|
559
|
+
return (msgObjs ? msgObjs.get(objId) : undefined);
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
private setIntoCache(
|
|
563
|
+
msgId: string, objId: string, obj: ObjVersionFile
|
|
564
|
+
): void {
|
|
565
|
+
let msgObjs = this.cache.get(msgId);
|
|
566
|
+
if (!msgObjs) {
|
|
567
|
+
msgObjs = new Map();
|
|
568
|
+
this.cache.set(msgId, msgObjs);
|
|
569
|
+
}
|
|
570
|
+
msgObjs.set(objId, obj);
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
async forNewFile(
|
|
574
|
+
msgId: string, objId: string
|
|
575
|
+
): Promise<ObjVersionFile> {
|
|
576
|
+
const path = this.objFileWritingPath(msgId, objId);
|
|
577
|
+
const objFile = await ObjVersionFile.createNew(path)
|
|
578
|
+
.catch((exc: fs.FileException) => {
|
|
579
|
+
if (exc.alreadyExists) { throw SC.OBJ_EXIST; }
|
|
580
|
+
throw exc;
|
|
581
|
+
});
|
|
582
|
+
this.setIntoCache(msgId, objId, objFile);
|
|
583
|
+
return objFile;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
async forExistingFile(
|
|
587
|
+
msgId: string, objId: string, forWriting = false
|
|
588
|
+
): Promise<ObjVersionFile> {
|
|
589
|
+
let objFile = this.getCached(msgId, objId);
|
|
590
|
+
if (!objFile) {
|
|
591
|
+
const path = (forWriting ?
|
|
592
|
+
this.objFileWritingPath(msgId, objId) :
|
|
593
|
+
this.objFileReadingPath(msgId, objId));
|
|
594
|
+
objFile = await ObjVersionFile.forExisting(path)
|
|
595
|
+
.catch((exc: fs.FileException) => {
|
|
596
|
+
if (exc.notFound) { throw SC.OBJ_UNKNOWN; }
|
|
597
|
+
throw exc;
|
|
598
|
+
});
|
|
599
|
+
this.setIntoCache(msgId, objId, objFile);
|
|
600
|
+
}
|
|
601
|
+
return objFile;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
private objFileWritingPath(msgId: string, objId: string): string {
|
|
605
|
+
return join(this.deliveryFolder, msgId, objId);
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
private objFileReadingPath(msgId: string, objId: string): string {
|
|
609
|
+
return join(this.readyMsgsFolder, msgId, objId);
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
changeToReadingPathsInMsg(msgId: string): void {
|
|
613
|
+
const msgObjs = this.cache.get(msgId);
|
|
614
|
+
if (!msgObjs) { return; }
|
|
615
|
+
for (const [ objId, obj ] of msgObjs.entries()) {
|
|
616
|
+
obj.changePathWithoutFileMove(this.objFileReadingPath(msgId, objId));
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
uncache(msgId: string): void {
|
|
621
|
+
this.cache.delete(msgId);
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
}
|
|
625
|
+
Object.freeze(ObjFiles.prototype);
|
|
626
|
+
Object.freeze(ObjFiles);
|
|
627
|
+
|
|
628
|
+
class MsgMetas {
|
|
629
|
+
|
|
630
|
+
private cache: TimeWindowCache<string|null, MsgMeta>;
|
|
631
|
+
private saveProcs = new NamedProcs();
|
|
632
|
+
|
|
633
|
+
constructor(
|
|
634
|
+
cachePeriodMillis: number,
|
|
635
|
+
public deliveryFolder: string,
|
|
636
|
+
public readyMsgsFolder: string
|
|
637
|
+
) {
|
|
638
|
+
this.cache = new TimeWindowCache(cachePeriodMillis);
|
|
639
|
+
Object.freeze(this);
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
async get(msgId: string, completeMsg: boolean): Promise<MsgMeta> {
|
|
643
|
+
let meta = this.cache.get(msgId);
|
|
644
|
+
if (meta) {
|
|
645
|
+
if ((meta.deliveryCompletion && !completeMsg)
|
|
646
|
+
|| (!meta.deliveryCompletion && completeMsg)) {
|
|
647
|
+
throw SC.MSG_UNKNOWN;
|
|
648
|
+
}
|
|
649
|
+
} else {
|
|
650
|
+
meta = await this.fromFile(msgId, completeMsg);
|
|
651
|
+
this.cache.set(msgId, meta);
|
|
652
|
+
}
|
|
653
|
+
return meta;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
private async fromFile(
|
|
657
|
+
msgId: string, completeMsg: boolean
|
|
658
|
+
): Promise<MsgMeta> {
|
|
659
|
+
const filePath = join(
|
|
660
|
+
(completeMsg ? this.readyMsgsFolder : this.deliveryFolder),
|
|
661
|
+
msgId, META_FILE);
|
|
662
|
+
const str = await fs.readFile(filePath, { encoding: 'utf8', flag: 'r' })
|
|
663
|
+
.catch((exc: fs.FileException) => {
|
|
664
|
+
if (exc.notFound) {
|
|
665
|
+
throw SC.MSG_UNKNOWN;
|
|
666
|
+
}
|
|
667
|
+
throw exc;
|
|
668
|
+
});
|
|
669
|
+
try {
|
|
670
|
+
return JSON.parse(str) as MsgMeta;
|
|
671
|
+
} catch (err) {
|
|
672
|
+
throw errWithCause(err, `Can't parse content of message meta file`);
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
async set(msgId: string, meta: MsgMeta): Promise<void> {
|
|
677
|
+
this.cache.set(msgId, meta);
|
|
678
|
+
await this.saveToFile(msgId, meta);
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
private async saveToFile(msgId: string, meta: MsgMeta): Promise<void> {
|
|
682
|
+
const filePath = join(this.deliveryFolder, msgId, META_FILE);
|
|
683
|
+
await this.saveProcs.startOrChain(msgId, () => fs.writeFile(
|
|
684
|
+
filePath, JSON.stringify(meta), { encoding: 'utf8', flag: 'w' }));
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
uncache(msgId: string): void {
|
|
688
|
+
this.cache.delete(msgId);
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
}
|
|
692
|
+
Object.freeze(MsgMetas.prototype);
|
|
693
|
+
Object.freeze(MsgMetas);
|
|
694
|
+
|
|
695
|
+
|
|
696
|
+
Object.freeze(exports);
|