@backblaze-labs/b2-sdk 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -1
- package/README.md +18 -5
- package/dist/_virtual/_b2-sdk-version-json.cjs +1 -1
- package/dist/_virtual/_b2-sdk-version-json.js +1 -1
- package/dist/auth/reauth-coalescer.cjs +65 -0
- package/dist/auth/reauth-coalescer.cjs.map +1 -0
- package/dist/auth/reauth-coalescer.d.cts +34 -0
- package/dist/auth/reauth-coalescer.d.cts.map +1 -0
- package/dist/auth/reauth-coalescer.d.ts +34 -0
- package/dist/auth/reauth-coalescer.d.ts.map +1 -0
- package/dist/auth/reauth-coalescer.js +65 -0
- package/dist/auth/reauth-coalescer.js.map +1 -0
- package/dist/backup/raw.cjs +37 -15
- package/dist/backup/raw.cjs.map +1 -1
- package/dist/backup/raw.d.cts +2 -2
- package/dist/backup/raw.d.cts.map +1 -1
- package/dist/backup/raw.d.ts +2 -2
- package/dist/backup/raw.d.ts.map +1 -1
- package/dist/backup/raw.js +37 -15
- package/dist/backup/raw.js.map +1 -1
- package/dist/bucket-validation.cjs +111 -0
- package/dist/bucket-validation.cjs.map +1 -0
- package/dist/bucket-validation.d.cts +27 -0
- package/dist/bucket-validation.d.cts.map +1 -0
- package/dist/bucket-validation.d.ts +27 -0
- package/dist/bucket-validation.d.ts.map +1 -0
- package/dist/bucket-validation.js +109 -0
- package/dist/bucket-validation.js.map +1 -0
- package/dist/bucket.cjs +123 -73
- package/dist/bucket.cjs.map +1 -1
- package/dist/bucket.d.cts +156 -61
- package/dist/bucket.d.cts.map +1 -1
- package/dist/bucket.d.ts +156 -61
- package/dist/bucket.d.ts.map +1 -1
- package/dist/bucket.js +123 -73
- package/dist/bucket.js.map +1 -1
- package/dist/client.cjs +29 -8
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +30 -9
- package/dist/client.d.cts.map +1 -1
- package/dist/client.d.ts +30 -9
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +29 -8
- package/dist/client.js.map +1 -1
- package/dist/download/single.cjs +38 -13
- package/dist/download/single.cjs.map +1 -1
- package/dist/download/single.d.cts +10 -4
- package/dist/download/single.d.cts.map +1 -1
- package/dist/download/single.d.ts +10 -4
- package/dist/download/single.d.ts.map +1 -1
- package/dist/download/single.js +38 -13
- package/dist/download/single.js.map +1 -1
- package/dist/errors/index.cjs +27 -4
- package/dist/errors/index.cjs.map +1 -1
- package/dist/errors/index.d.cts +15 -0
- package/dist/errors/index.d.cts.map +1 -1
- package/dist/errors/index.d.ts +15 -0
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +27 -5
- package/dist/errors/index.js.map +1 -1
- package/dist/http/non-idempotent-mutations.cjs +38 -0
- package/dist/http/non-idempotent-mutations.cjs.map +1 -0
- package/dist/http/non-idempotent-mutations.d.cts +25 -0
- package/dist/http/non-idempotent-mutations.d.cts.map +1 -0
- package/dist/http/non-idempotent-mutations.d.ts +25 -0
- package/dist/http/non-idempotent-mutations.d.ts.map +1 -0
- package/dist/http/non-idempotent-mutations.js +35 -0
- package/dist/http/non-idempotent-mutations.js.map +1 -0
- package/dist/http/transport.cjs +9 -8
- package/dist/http/transport.cjs.map +1 -1
- package/dist/http/transport.d.cts +5 -0
- package/dist/http/transport.d.cts.map +1 -1
- package/dist/http/transport.d.ts +5 -0
- package/dist/http/transport.d.ts.map +1 -1
- package/dist/http/transport.js +9 -8
- package/dist/http/transport.js.map +1 -1
- package/dist/http/user-agent.cjs +12 -1
- package/dist/http/user-agent.cjs.map +1 -1
- package/dist/http/user-agent.d.cts +8 -0
- package/dist/http/user-agent.d.cts.map +1 -1
- package/dist/http/user-agent.d.ts +8 -0
- package/dist/http/user-agent.d.ts.map +1 -1
- package/dist/http/user-agent.js +13 -3
- package/dist/http/user-agent.js.map +1 -1
- package/dist/index.cjs +25 -0
- package/dist/index.d.cts +10 -9
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +10 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -6
- package/dist/notifications/index.cjs +3 -0
- package/dist/notifications/index.d.cts +2 -0
- package/dist/notifications/index.d.cts.map +1 -1
- package/dist/notifications/index.d.ts +2 -0
- package/dist/notifications/index.d.ts.map +1 -1
- package/dist/notifications/index.js +2 -1
- package/dist/object.cjs +12 -1
- package/dist/object.cjs.map +1 -1
- package/dist/object.d.cts +7 -1
- package/dist/object.d.cts.map +1 -1
- package/dist/object.d.ts +7 -1
- package/dist/object.d.ts.map +1 -1
- package/dist/object.js +12 -1
- package/dist/object.js.map +1 -1
- package/dist/partner/auth-core.cjs +4 -23
- package/dist/partner/auth-core.cjs.map +1 -1
- package/dist/partner/auth-core.d.cts +1 -1
- package/dist/partner/auth-core.d.cts.map +1 -1
- package/dist/partner/auth-core.d.ts +1 -1
- package/dist/partner/auth-core.d.ts.map +1 -1
- package/dist/partner/auth-core.js +5 -24
- package/dist/partner/auth-core.js.map +1 -1
- package/dist/partner/client.cjs +25 -10
- package/dist/partner/client.cjs.map +1 -1
- package/dist/partner/client.d.cts +32 -10
- package/dist/partner/client.d.cts.map +1 -1
- package/dist/partner/client.d.ts +32 -10
- package/dist/partner/client.d.ts.map +1 -1
- package/dist/partner/client.js +25 -10
- package/dist/partner/client.js.map +1 -1
- package/dist/partner/endpoint-url.cjs +1 -0
- package/dist/partner/endpoint-url.cjs.map +1 -1
- package/dist/partner/endpoint-url.d.cts +2 -0
- package/dist/partner/endpoint-url.d.cts.map +1 -1
- package/dist/partner/endpoint-url.d.ts +2 -0
- package/dist/partner/endpoint-url.d.ts.map +1 -1
- package/dist/partner/endpoint-url.js +1 -0
- package/dist/partner/endpoint-url.js.map +1 -1
- package/dist/partner/in-memory.cjs.map +1 -1
- package/dist/partner/in-memory.js.map +1 -1
- package/dist/partner/index.cjs +9 -0
- package/dist/partner/index.d.cts +11 -2
- package/dist/partner/index.d.cts.map +1 -1
- package/dist/partner/index.d.ts +11 -2
- package/dist/partner/index.d.ts.map +1 -1
- package/dist/partner/index.js +3 -1
- package/dist/partner/raw.cjs +52 -44
- package/dist/partner/raw.cjs.map +1 -1
- package/dist/partner/raw.d.cts +16 -19
- package/dist/partner/raw.d.cts.map +1 -1
- package/dist/partner/raw.d.ts +16 -19
- package/dist/partner/raw.d.ts.map +1 -1
- package/dist/partner/raw.js +52 -44
- package/dist/partner/raw.js.map +1 -1
- package/dist/partner/redaction.cjs +133 -108
- package/dist/partner/redaction.cjs.map +1 -1
- package/dist/partner/redaction.d.cts +47 -13
- package/dist/partner/redaction.d.cts.map +1 -1
- package/dist/partner/redaction.d.ts +47 -13
- package/dist/partner/redaction.d.ts.map +1 -1
- package/dist/partner/redaction.js +133 -109
- package/dist/partner/redaction.js.map +1 -1
- package/dist/raw/encoding.cjs +29 -10
- package/dist/raw/encoding.cjs.map +1 -1
- package/dist/raw/encoding.d.cts +3 -2
- package/dist/raw/encoding.d.cts.map +1 -1
- package/dist/raw/encoding.d.ts +3 -2
- package/dist/raw/encoding.d.ts.map +1 -1
- package/dist/raw/encoding.js +29 -10
- package/dist/raw/encoding.js.map +1 -1
- package/dist/raw/index.cjs +64 -39
- package/dist/raw/index.cjs.map +1 -1
- package/dist/raw/index.d.cts +21 -19
- package/dist/raw/index.d.cts.map +1 -1
- package/dist/raw/index.d.ts +21 -19
- package/dist/raw/index.d.ts.map +1 -1
- package/dist/raw/index.js +47 -40
- package/dist/raw/index.js.map +1 -1
- package/dist/raw/url.cjs.map +1 -1
- package/dist/raw/url.d.cts +3 -3
- package/dist/raw/url.d.ts +3 -3
- package/dist/raw/url.js.map +1 -1
- package/dist/simulator/index.cjs +456 -125
- package/dist/simulator/index.cjs.map +1 -1
- package/dist/simulator/index.d.cts +16 -1
- package/dist/simulator/index.d.cts.map +1 -1
- package/dist/simulator/index.d.ts +16 -1
- package/dist/simulator/index.d.ts.map +1 -1
- package/dist/simulator/index.js +449 -130
- package/dist/simulator/index.js.map +1 -1
- package/dist/simulator/partner-capabilities.cjs +77 -0
- package/dist/simulator/partner-capabilities.cjs.map +1 -0
- package/dist/simulator/partner-capabilities.d.cts +53 -0
- package/dist/simulator/partner-capabilities.d.cts.map +1 -0
- package/dist/simulator/partner-capabilities.d.ts +53 -0
- package/dist/simulator/partner-capabilities.d.ts.map +1 -0
- package/dist/simulator/partner-capabilities.js +73 -0
- package/dist/simulator/partner-capabilities.js.map +1 -0
- package/dist/simulator/partner.cjs +55 -61
- package/dist/simulator/partner.cjs.map +1 -1
- package/dist/simulator/partner.d.cts +5 -2
- package/dist/simulator/partner.d.cts.map +1 -1
- package/dist/simulator/partner.d.ts +5 -2
- package/dist/simulator/partner.d.ts.map +1 -1
- package/dist/simulator/partner.js +56 -61
- package/dist/simulator/partner.js.map +1 -1
- package/dist/simulator/validation.cjs +160 -30
- package/dist/simulator/validation.cjs.map +1 -1
- package/dist/simulator/validation.d.cts +28 -6
- package/dist/simulator/validation.d.cts.map +1 -1
- package/dist/simulator/validation.d.ts +28 -6
- package/dist/simulator/validation.d.ts.map +1 -1
- package/dist/simulator/validation.js +148 -31
- package/dist/simulator/validation.js.map +1 -1
- package/dist/streams/file-source.cjs +1 -1
- package/dist/streams/file-source.cjs.map +1 -1
- package/dist/streams/file-source.js +1 -1
- package/dist/streams/file-source.js.map +1 -1
- package/dist/streams/hash.cjs +246 -13
- package/dist/streams/hash.cjs.map +1 -1
- package/dist/streams/hash.d.cts +37 -12
- package/dist/streams/hash.d.cts.map +1 -1
- package/dist/streams/hash.d.ts +37 -12
- package/dist/streams/hash.d.ts.map +1 -1
- package/dist/streams/hash.js +246 -15
- package/dist/streams/hash.js.map +1 -1
- package/dist/streams/index.cjs +2 -0
- package/dist/streams/index.d.cts +1 -1
- package/dist/streams/index.d.cts.map +1 -1
- package/dist/streams/index.d.ts +1 -1
- package/dist/streams/index.d.ts.map +1 -1
- package/dist/streams/index.js +2 -2
- package/dist/streams/progress.cjs +63 -4
- package/dist/streams/progress.cjs.map +1 -1
- package/dist/streams/progress.d.cts +28 -2
- package/dist/streams/progress.d.cts.map +1 -1
- package/dist/streams/progress.d.ts +28 -2
- package/dist/streams/progress.d.ts.map +1 -1
- package/dist/streams/progress.js +63 -4
- package/dist/streams/progress.js.map +1 -1
- package/dist/sync/download-staging.cjs +147 -35
- package/dist/sync/download-staging.cjs.map +1 -1
- package/dist/sync/download-staging.d.cts +25 -2
- package/dist/sync/download-staging.d.cts.map +1 -1
- package/dist/sync/download-staging.d.ts +25 -2
- package/dist/sync/download-staging.d.ts.map +1 -1
- package/dist/sync/download-staging.js +146 -36
- package/dist/sync/download-staging.js.map +1 -1
- package/dist/sync/index.d.cts +1 -1
- package/dist/sync/index.d.cts.map +1 -1
- package/dist/sync/index.d.ts +1 -1
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/local-file-io.cjs +5 -1
- package/dist/sync/local-file-io.cjs.map +1 -1
- package/dist/sync/local-file-io.d.cts +2 -0
- package/dist/sync/local-file-io.d.cts.map +1 -1
- package/dist/sync/local-file-io.d.ts +2 -0
- package/dist/sync/local-file-io.d.ts.map +1 -1
- package/dist/sync/local-file-io.js +5 -1
- package/dist/sync/local-file-io.js.map +1 -1
- package/dist/sync/pairing.cjs +1 -0
- package/dist/sync/pairing.cjs.map +1 -1
- package/dist/sync/pairing.js +1 -0
- package/dist/sync/pairing.js.map +1 -1
- package/dist/sync/scanners/b2.cjs +2 -0
- package/dist/sync/scanners/b2.cjs.map +1 -1
- package/dist/sync/scanners/b2.d.cts.map +1 -1
- package/dist/sync/scanners/b2.d.ts.map +1 -1
- package/dist/sync/scanners/b2.js +2 -0
- package/dist/sync/scanners/b2.js.map +1 -1
- package/dist/sync/scanners/local.cjs +150 -33
- package/dist/sync/scanners/local.cjs.map +1 -1
- package/dist/sync/scanners/local.d.cts +6 -0
- package/dist/sync/scanners/local.d.cts.map +1 -1
- package/dist/sync/scanners/local.d.ts +6 -0
- package/dist/sync/scanners/local.d.ts.map +1 -1
- package/dist/sync/scanners/local.js +150 -33
- package/dist/sync/scanners/local.js.map +1 -1
- package/dist/sync/synchronizer.cjs +76 -29
- package/dist/sync/synchronizer.cjs.map +1 -1
- package/dist/sync/synchronizer.d.cts +1 -0
- package/dist/sync/synchronizer.d.cts.map +1 -1
- package/dist/sync/synchronizer.d.ts +1 -0
- package/dist/sync/synchronizer.d.ts.map +1 -1
- package/dist/sync/synchronizer.js +76 -29
- package/dist/sync/synchronizer.js.map +1 -1
- package/dist/sync/types.d.cts +19 -3
- package/dist/sync/types.d.cts.map +1 -1
- package/dist/sync/types.d.ts +19 -3
- package/dist/sync/types.d.ts.map +1 -1
- package/dist/types/backup.d.cts +6 -1
- package/dist/types/backup.d.cts.map +1 -1
- package/dist/types/backup.d.ts +6 -1
- package/dist/types/backup.d.ts.map +1 -1
- package/dist/types/bucket.cjs +81 -11
- package/dist/types/bucket.cjs.map +1 -1
- package/dist/types/bucket.d.cts +190 -39
- package/dist/types/bucket.d.cts.map +1 -1
- package/dist/types/bucket.d.ts +190 -39
- package/dist/types/bucket.d.ts.map +1 -1
- package/dist/types/bucket.js +67 -12
- package/dist/types/bucket.js.map +1 -1
- package/dist/types/download.cjs.map +1 -1
- package/dist/types/download.d.cts +3 -17
- package/dist/types/download.d.cts.map +1 -1
- package/dist/types/download.d.ts +3 -17
- package/dist/types/download.d.ts.map +1 -1
- package/dist/types/download.js.map +1 -1
- package/dist/types/encryption.cjs +18 -0
- package/dist/types/encryption.cjs.map +1 -1
- package/dist/types/encryption.d.cts +21 -11
- package/dist/types/encryption.d.cts.map +1 -1
- package/dist/types/encryption.d.ts +21 -11
- package/dist/types/encryption.d.ts.map +1 -1
- package/dist/types/encryption.js +18 -0
- package/dist/types/encryption.js.map +1 -1
- package/dist/types/file.cjs +3 -0
- package/dist/types/file.cjs.map +1 -1
- package/dist/types/file.d.cts +125 -16
- package/dist/types/file.d.cts.map +1 -1
- package/dist/types/file.d.ts +125 -16
- package/dist/types/file.d.ts.map +1 -1
- package/dist/types/file.js +3 -1
- package/dist/types/file.js.map +1 -1
- package/dist/types/index.d.cts +7 -7
- package/dist/types/index.d.cts.map +1 -1
- package/dist/types/index.d.ts +7 -7
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/key.d.cts +4 -3
- package/dist/types/key.d.cts.map +1 -1
- package/dist/types/key.d.ts +4 -3
- package/dist/types/key.d.ts.map +1 -1
- package/dist/types/notifications.cjs +30 -0
- package/dist/types/notifications.cjs.map +1 -1
- package/dist/types/notifications.d.cts +26 -1
- package/dist/types/notifications.d.cts.map +1 -1
- package/dist/types/notifications.d.ts +26 -1
- package/dist/types/notifications.d.ts.map +1 -1
- package/dist/types/notifications.js +29 -1
- package/dist/types/notifications.js.map +1 -1
- package/dist/types/partner.cjs.map +1 -1
- package/dist/types/partner.d.cts +28 -36
- package/dist/types/partner.d.cts.map +1 -1
- package/dist/types/partner.d.ts +28 -36
- package/dist/types/partner.d.ts.map +1 -1
- package/dist/types/partner.js.map +1 -1
- package/dist/types/upload.d.cts +4 -0
- package/dist/types/upload.d.cts.map +1 -1
- package/dist/types/upload.d.ts +4 -0
- package/dist/types/upload.d.ts.map +1 -1
- package/dist/upload/large.cjs +10 -7
- package/dist/upload/large.cjs.map +1 -1
- package/dist/upload/large.d.cts +15 -6
- package/dist/upload/large.d.cts.map +1 -1
- package/dist/upload/large.d.ts +15 -6
- package/dist/upload/large.d.ts.map +1 -1
- package/dist/upload/large.js +10 -7
- package/dist/upload/large.js.map +1 -1
- package/dist/upload/options.cjs.map +1 -1
- package/dist/upload/options.d.cts +12 -0
- package/dist/upload/options.d.cts.map +1 -1
- package/dist/upload/options.d.ts +12 -0
- package/dist/upload/options.d.ts.map +1 -1
- package/dist/upload/options.js.map +1 -1
- package/dist/upload/resume.cjs +4 -3
- package/dist/upload/resume.cjs.map +1 -1
- package/dist/upload/resume.d.cts +6 -4
- package/dist/upload/resume.d.cts.map +1 -1
- package/dist/upload/resume.d.ts +6 -4
- package/dist/upload/resume.d.ts.map +1 -1
- package/dist/upload/resume.js +4 -3
- package/dist/upload/resume.js.map +1 -1
- package/dist/upload/retry.cjs +17 -10
- package/dist/upload/retry.cjs.map +1 -1
- package/dist/upload/retry.d.cts.map +1 -1
- package/dist/upload/retry.d.ts.map +1 -1
- package/dist/upload/retry.js +17 -10
- package/dist/upload/retry.js.map +1 -1
- package/dist/upload/single.cjs +35 -31
- package/dist/upload/single.cjs.map +1 -1
- package/dist/upload/single.d.cts +6 -0
- package/dist/upload/single.d.cts.map +1 -1
- package/dist/upload/single.d.ts +6 -0
- package/dist/upload/single.d.ts.map +1 -1
- package/dist/upload/single.js +35 -31
- package/dist/upload/single.js.map +1 -1
- package/dist/upload/stream.cjs +12 -1
- package/dist/upload/stream.cjs.map +1 -1
- package/dist/upload/stream.d.cts +6 -0
- package/dist/upload/stream.d.cts.map +1 -1
- package/dist/upload/stream.d.ts +6 -0
- package/dist/upload/stream.d.ts.map +1 -1
- package/dist/upload/stream.js +12 -1
- package/dist/upload/stream.js.map +1 -1
- package/dist/version.cjs +56 -4
- package/dist/version.cjs.map +1 -1
- package/dist/version.d.cts +53 -4
- package/dist/version.d.cts.map +1 -1
- package/dist/version.d.ts +53 -4
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +52 -5
- package/dist/version.js.map +1 -1
- package/package.json +11 -4
package/dist/simulator/index.cjs
CHANGED
|
@@ -13,6 +13,7 @@ const require_bucket = require("../types/bucket.cjs");
|
|
|
13
13
|
const require_to_error = require("../util/to-error.cjs");
|
|
14
14
|
const require_url = require("../raw/url.cjs");
|
|
15
15
|
const require_auth = require("../types/auth.cjs");
|
|
16
|
+
const require_partner_capabilities = require("./partner-capabilities.cjs");
|
|
16
17
|
const require_partner = require("./partner.cjs");
|
|
17
18
|
const require_capabilities = require("./capabilities.cjs");
|
|
18
19
|
const require_b2_naming = require("../internal/b2-naming.cjs");
|
|
@@ -56,9 +57,22 @@ var SIMULATOR_MASTER_CAPABILITIES = [
|
|
|
56
57
|
function apiPathParts(path) {
|
|
57
58
|
const segments = path.split("/").filter((segment) => segment.length > 0);
|
|
58
59
|
const candidate = segments.at(-2);
|
|
60
|
+
const endpoint = segments.at(-1) ?? "";
|
|
61
|
+
const isB2ApiPath = segments.at(-3) === "b2api";
|
|
62
|
+
if (candidate !== void 0 && require_url.isB2ApiVersion(candidate)) {
|
|
63
|
+
if (candidate === "v3" || candidate === "v4") return {
|
|
64
|
+
endpoint,
|
|
65
|
+
version: candidate
|
|
66
|
+
};
|
|
67
|
+
if (isB2ApiPath) return {
|
|
68
|
+
endpoint,
|
|
69
|
+
version: "v3",
|
|
70
|
+
unsupportedVersion: candidate
|
|
71
|
+
};
|
|
72
|
+
}
|
|
59
73
|
return {
|
|
60
|
-
endpoint
|
|
61
|
-
version:
|
|
74
|
+
endpoint,
|
|
75
|
+
version: "v3"
|
|
62
76
|
};
|
|
63
77
|
}
|
|
64
78
|
function parseBasicAuthorizationHeader(authzHeader) {
|
|
@@ -191,6 +205,11 @@ function compareB2FileNames(a, b) {
|
|
|
191
205
|
if (a > b) return 1;
|
|
192
206
|
return 0;
|
|
193
207
|
}
|
|
208
|
+
function compareFileVersionListEntries(a, b) {
|
|
209
|
+
const nameCmp = compareB2FileNames(a.fileName, b.fileName);
|
|
210
|
+
if (nameCmp !== 0) return nameCmp;
|
|
211
|
+
return b.uploadTimestamp - a.uploadTimestamp;
|
|
212
|
+
}
|
|
194
213
|
var DOWNLOAD_AUTH_TOKEN_BYTES = 32;
|
|
195
214
|
var DOWNLOAD_AUTH_TOKEN_PREFIX = "sim_dl_auth_";
|
|
196
215
|
var DOWNLOAD_AUTH_PURGE_BATCH_SIZE = 128;
|
|
@@ -284,6 +303,44 @@ function normalizeReplicationConfiguration(config) {
|
|
|
284
303
|
asReplicationDestination: config.asReplicationDestination ?? null
|
|
285
304
|
};
|
|
286
305
|
}
|
|
306
|
+
function wrapReplicationConfiguration(config) {
|
|
307
|
+
if (config === void 0) return {
|
|
308
|
+
isClientAuthorizedToRead: true,
|
|
309
|
+
value: null
|
|
310
|
+
};
|
|
311
|
+
const normalized = normalizeReplicationConfiguration(config);
|
|
312
|
+
return {
|
|
313
|
+
isClientAuthorizedToRead: true,
|
|
314
|
+
value: normalized.asReplicationSource === null && normalized.asReplicationDestination === null ? null : normalized
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
function filterReadableReplicationConfiguration(config, canRead) {
|
|
318
|
+
return canRead ? {
|
|
319
|
+
isClientAuthorizedToRead: true,
|
|
320
|
+
value: config.value
|
|
321
|
+
} : {
|
|
322
|
+
isClientAuthorizedToRead: false,
|
|
323
|
+
value: null
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
function readableFileRetention(value, canRead) {
|
|
327
|
+
return canRead ? {
|
|
328
|
+
isClientAuthorizedToRead: true,
|
|
329
|
+
value
|
|
330
|
+
} : {
|
|
331
|
+
isClientAuthorizedToRead: false,
|
|
332
|
+
value: null
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
function readableLegalHold(value, canRead) {
|
|
336
|
+
return canRead ? {
|
|
337
|
+
isClientAuthorizedToRead: true,
|
|
338
|
+
value
|
|
339
|
+
} : {
|
|
340
|
+
isClientAuthorizedToRead: false,
|
|
341
|
+
value: null
|
|
342
|
+
};
|
|
343
|
+
}
|
|
287
344
|
function validateBucketConfigurationFields(fields, options) {
|
|
288
345
|
if (fields.bucketInfo !== void 0) {
|
|
289
346
|
const infoError = require_validation.validateBucketInfo(fields.bucketInfo);
|
|
@@ -297,6 +354,10 @@ function validateBucketConfigurationFields(fields, options) {
|
|
|
297
354
|
const lifecycleError = require_validation.validateLifecycleRules(fields.lifecycleRules);
|
|
298
355
|
if (lifecycleError) return lifecycleError;
|
|
299
356
|
}
|
|
357
|
+
if (fields.defaultServerSideEncryption !== void 0) {
|
|
358
|
+
const encryptionError = validateBucketDefaultServerSideEncryption(fields.defaultServerSideEncryption);
|
|
359
|
+
if (encryptionError) return encryptionError;
|
|
360
|
+
}
|
|
300
361
|
if (fields.replicationConfiguration !== void 0) {
|
|
301
362
|
const replicationError = require_validation.validateReplicationConfiguration(fields.replicationConfiguration);
|
|
302
363
|
if (replicationError) return replicationError;
|
|
@@ -311,6 +372,34 @@ function validateBucketConfigurationFields(fields, options) {
|
|
|
311
372
|
}
|
|
312
373
|
return null;
|
|
313
374
|
}
|
|
375
|
+
function validateBucketDefaultServerSideEncryption(encryption) {
|
|
376
|
+
const runtimeEncryption = requestRecord(encryption);
|
|
377
|
+
if (runtimeEncryption === null) return {
|
|
378
|
+
code: "bad_request",
|
|
379
|
+
message: "defaultServerSideEncryption must be an object"
|
|
380
|
+
};
|
|
381
|
+
if (hasCustomerEncryptionFields(runtimeEncryption)) return {
|
|
382
|
+
code: "bad_request",
|
|
383
|
+
message: "Bucket default server-side encryption cannot use SSE-C"
|
|
384
|
+
};
|
|
385
|
+
const mode = runtimeEncryption["mode"];
|
|
386
|
+
if (mode === require_encryption.EncryptionMode.None) return null;
|
|
387
|
+
if (mode === require_encryption.EncryptionMode.SseB2) {
|
|
388
|
+
if (runtimeEncryption["algorithm"] !== require_encryption.EncryptionAlgorithm.Aes256) return {
|
|
389
|
+
code: "bad_request",
|
|
390
|
+
message: "SSE-B2 algorithm must be AES256"
|
|
391
|
+
};
|
|
392
|
+
return null;
|
|
393
|
+
}
|
|
394
|
+
if (mode === require_encryption.EncryptionMode.SseC) return {
|
|
395
|
+
code: "bad_request",
|
|
396
|
+
message: "Bucket default server-side encryption cannot use SSE-C"
|
|
397
|
+
};
|
|
398
|
+
return {
|
|
399
|
+
code: "bad_request",
|
|
400
|
+
message: `Unsupported bucket default server-side encryption mode: ${String(mode)}`
|
|
401
|
+
};
|
|
402
|
+
}
|
|
314
403
|
function nextObjectLockEnabled(current, requested) {
|
|
315
404
|
if (requested === void 0) return current;
|
|
316
405
|
if (typeof requested !== "boolean") return {
|
|
@@ -353,59 +442,188 @@ function fileNames(...names) {
|
|
|
353
442
|
const present = names.filter((name) => name !== void 0);
|
|
354
443
|
return present.length > 0 ? present : void 0;
|
|
355
444
|
}
|
|
356
|
-
function queryParamsBody(params) {
|
|
445
|
+
function queryParamsBody(params, endpoint) {
|
|
446
|
+
const metadata = jsonEndpointMetadata(endpoint);
|
|
447
|
+
const queryFields = new Set(metadata?.queryFields ?? []);
|
|
448
|
+
const numericFields = new Set(metadata?.numericQueryFields ?? []);
|
|
357
449
|
const body = Object.create(null);
|
|
358
|
-
let hasParams = false;
|
|
359
450
|
for (const [key, value] of params) {
|
|
451
|
+
if (!queryFields.has(key)) continue;
|
|
360
452
|
if (body[key] !== void 0) continue;
|
|
361
|
-
body[key] = value;
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
]
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
]
|
|
453
|
+
body[key] = queryParamValue(value, numericFields.has(key));
|
|
454
|
+
}
|
|
455
|
+
return body;
|
|
456
|
+
}
|
|
457
|
+
function queryParamValue(value, numeric) {
|
|
458
|
+
if (!numeric || !/^-?\d+$/.test(value)) return value;
|
|
459
|
+
const numericValue = Number(value);
|
|
460
|
+
return Number.isSafeInteger(numericValue) ? numericValue : value;
|
|
461
|
+
}
|
|
462
|
+
var JSON_ENDPOINTS = {
|
|
463
|
+
b2_authorize_account: { methods: ["GET"] },
|
|
464
|
+
[require_partner_capabilities.PartnerEndpoint.ListGroups]: {
|
|
465
|
+
methods: ["GET"],
|
|
466
|
+
queryFields: [
|
|
467
|
+
"adminAccountId",
|
|
468
|
+
"groupName",
|
|
469
|
+
"startGroupId",
|
|
470
|
+
"maxGroupCount"
|
|
471
|
+
],
|
|
472
|
+
numericQueryFields: ["maxGroupCount"]
|
|
473
|
+
},
|
|
474
|
+
[require_partner_capabilities.PartnerEndpoint.ListGroupMembers]: {
|
|
475
|
+
methods: ["GET"],
|
|
476
|
+
queryFields: [
|
|
477
|
+
"adminAccountId",
|
|
478
|
+
"groupId",
|
|
479
|
+
"startEmail",
|
|
480
|
+
"maxMemberCount"
|
|
481
|
+
],
|
|
482
|
+
numericQueryFields: ["maxMemberCount"]
|
|
483
|
+
},
|
|
484
|
+
[require_partner_capabilities.PartnerEndpoint.ListComputers]: {
|
|
485
|
+
methods: ["GET"],
|
|
486
|
+
queryFields: [
|
|
487
|
+
"accountId",
|
|
488
|
+
"startComputerId",
|
|
489
|
+
"maxComputerCount"
|
|
490
|
+
],
|
|
491
|
+
numericQueryFields: ["maxComputerCount"]
|
|
492
|
+
},
|
|
493
|
+
b2_get_upload_url: {
|
|
494
|
+
methods: ["GET", "POST"],
|
|
495
|
+
queryFields: ["bucketId"]
|
|
496
|
+
},
|
|
497
|
+
b2_list_file_names: {
|
|
498
|
+
methods: ["GET", "POST"],
|
|
499
|
+
queryFields: [
|
|
500
|
+
"bucketId",
|
|
501
|
+
"delimiter",
|
|
502
|
+
"maxFileCount",
|
|
503
|
+
"prefix",
|
|
504
|
+
"startFileName"
|
|
505
|
+
],
|
|
506
|
+
numericQueryFields: ["maxFileCount"]
|
|
507
|
+
},
|
|
508
|
+
b2_list_file_versions: {
|
|
509
|
+
methods: ["GET", "POST"],
|
|
510
|
+
queryFields: [
|
|
511
|
+
"bucketId",
|
|
512
|
+
"delimiter",
|
|
513
|
+
"maxFileCount",
|
|
514
|
+
"prefix",
|
|
515
|
+
"startFileName",
|
|
516
|
+
"startFileId"
|
|
517
|
+
],
|
|
518
|
+
numericQueryFields: ["maxFileCount"]
|
|
519
|
+
},
|
|
520
|
+
b2_get_file_info: {
|
|
521
|
+
methods: ["GET", "POST"],
|
|
522
|
+
queryFields: ["fileId"]
|
|
523
|
+
},
|
|
524
|
+
b2_copy_file: {
|
|
525
|
+
methods: ["GET", "POST"],
|
|
526
|
+
queryFields: [
|
|
527
|
+
"sourceFileId",
|
|
528
|
+
"fileName",
|
|
529
|
+
"destinationBucketId",
|
|
530
|
+
"range",
|
|
531
|
+
"metadataDirective",
|
|
532
|
+
"contentType"
|
|
533
|
+
]
|
|
534
|
+
},
|
|
535
|
+
b2_get_upload_part_url: {
|
|
536
|
+
methods: ["GET", "POST"],
|
|
537
|
+
queryFields: ["fileId"]
|
|
538
|
+
},
|
|
539
|
+
b2_list_unfinished_large_files: {
|
|
540
|
+
methods: ["GET", "POST"],
|
|
541
|
+
queryFields: [
|
|
542
|
+
"bucketId",
|
|
543
|
+
"namePrefix",
|
|
544
|
+
"startFileId",
|
|
545
|
+
"maxFileCount"
|
|
546
|
+
],
|
|
547
|
+
numericQueryFields: ["maxFileCount"]
|
|
548
|
+
},
|
|
549
|
+
b2_list_parts: {
|
|
550
|
+
methods: ["GET", "POST"],
|
|
551
|
+
queryFields: [
|
|
552
|
+
"fileId",
|
|
553
|
+
"startPartNumber",
|
|
554
|
+
"maxPartCount"
|
|
555
|
+
],
|
|
556
|
+
numericQueryFields: ["startPartNumber", "maxPartCount"]
|
|
557
|
+
},
|
|
558
|
+
b2_copy_part: {
|
|
559
|
+
methods: ["GET", "POST"],
|
|
560
|
+
queryFields: [
|
|
561
|
+
"sourceFileId",
|
|
562
|
+
"largeFileId",
|
|
563
|
+
"partNumber",
|
|
564
|
+
"range"
|
|
565
|
+
],
|
|
566
|
+
numericQueryFields: ["partNumber"]
|
|
567
|
+
},
|
|
568
|
+
b2_get_download_authorization: {
|
|
569
|
+
methods: ["GET", "POST"],
|
|
570
|
+
queryFields: [
|
|
571
|
+
"bucketId",
|
|
572
|
+
"fileNamePrefix",
|
|
573
|
+
"validDurationInSeconds",
|
|
574
|
+
"b2ContentDisposition",
|
|
575
|
+
"b2ContentLanguage",
|
|
576
|
+
"b2ContentEncoding",
|
|
577
|
+
"b2ContentType",
|
|
578
|
+
"b2CacheControl",
|
|
579
|
+
"b2Expires"
|
|
580
|
+
],
|
|
581
|
+
numericQueryFields: ["validDurationInSeconds"]
|
|
582
|
+
},
|
|
583
|
+
b2_list_keys: {
|
|
584
|
+
methods: ["GET", "POST"],
|
|
585
|
+
queryFields: [
|
|
586
|
+
"accountId",
|
|
587
|
+
"maxKeyCount",
|
|
588
|
+
"startApplicationKeyId"
|
|
589
|
+
],
|
|
590
|
+
numericQueryFields: ["maxKeyCount"]
|
|
591
|
+
},
|
|
592
|
+
b2_get_bucket_notification_rules: {
|
|
593
|
+
methods: ["GET", "POST"],
|
|
594
|
+
queryFields: ["bucketId"]
|
|
595
|
+
},
|
|
596
|
+
[require_partner_capabilities.PartnerEndpoint.CreateGroupMember]: { methods: ["POST"] },
|
|
597
|
+
[require_partner_capabilities.PartnerEndpoint.EjectGroupMember]: { methods: ["POST"] },
|
|
598
|
+
[require_partner_capabilities.PartnerEndpoint.ReserveTrialCreateAccount]: { methods: ["POST"] },
|
|
599
|
+
[require_partner_capabilities.PartnerEndpoint.DeleteComputer]: { methods: ["POST"] },
|
|
600
|
+
b2_create_bucket: { methods: ["POST"] },
|
|
601
|
+
b2_list_buckets: { methods: ["POST"] },
|
|
602
|
+
b2_delete_bucket: { methods: ["POST"] },
|
|
603
|
+
b2_update_bucket: { methods: ["POST"] },
|
|
604
|
+
b2_hide_file: { methods: ["POST"] },
|
|
605
|
+
b2_delete_file_version: { methods: ["POST"] },
|
|
606
|
+
b2_start_large_file: { methods: ["POST"] },
|
|
607
|
+
b2_finish_large_file: { methods: ["POST"] },
|
|
608
|
+
b2_cancel_large_file: { methods: ["POST"] },
|
|
609
|
+
b2_create_key: { methods: ["POST"] },
|
|
610
|
+
b2_delete_key: { methods: ["POST"] },
|
|
611
|
+
b2_update_file_retention: { methods: ["POST"] },
|
|
612
|
+
b2_update_file_legal_hold: { methods: ["POST"] },
|
|
613
|
+
b2_set_bucket_notification_rules: { methods: ["POST"] }
|
|
614
|
+
};
|
|
615
|
+
function jsonEndpointMetadata(endpoint) {
|
|
616
|
+
return JSON_ENDPOINTS[endpoint];
|
|
617
|
+
}
|
|
404
618
|
function jsonEndpointAllowsMethod(method, endpoint) {
|
|
619
|
+
const metadata = jsonEndpointMetadata(endpoint);
|
|
620
|
+
if (metadata === void 0) return true;
|
|
405
621
|
const normalizedMethod = method.toUpperCase();
|
|
406
|
-
if (
|
|
407
|
-
|
|
408
|
-
|
|
622
|
+
if (normalizedMethod !== "GET" && normalizedMethod !== "POST") return false;
|
|
623
|
+
return metadata.methods.includes(normalizedMethod);
|
|
624
|
+
}
|
|
625
|
+
function isJsonQueryEndpoint(endpoint) {
|
|
626
|
+
return jsonEndpointMetadata(endpoint)?.queryFields !== void 0;
|
|
409
627
|
}
|
|
410
628
|
function notificationRulePrefixes(body) {
|
|
411
629
|
if (typeof body !== "object" || body === null) return void 0;
|
|
@@ -441,6 +659,30 @@ function publicServerSideEncryption(encryption) {
|
|
|
441
659
|
};
|
|
442
660
|
return encryption;
|
|
443
661
|
}
|
|
662
|
+
function publicBucketDefaultServerSideEncryption(encryption) {
|
|
663
|
+
return {
|
|
664
|
+
isClientAuthorizedToRead: true,
|
|
665
|
+
value: publicBucketDefaultServerSideEncryptionValue(encryption)
|
|
666
|
+
};
|
|
667
|
+
}
|
|
668
|
+
function publicBucketDefaultServerSideEncryptionValue(encryption) {
|
|
669
|
+
if (encryption?.mode === require_encryption.EncryptionMode.SseB2) return encryption;
|
|
670
|
+
return {
|
|
671
|
+
mode: null,
|
|
672
|
+
algorithm: null
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
function bucketDefaultServerSideEncryptionForStorage(info) {
|
|
676
|
+
const encryption = info.defaultServerSideEncryption;
|
|
677
|
+
if (!encryption.isClientAuthorizedToRead) return {
|
|
678
|
+
mode: null,
|
|
679
|
+
algorithm: null
|
|
680
|
+
};
|
|
681
|
+
return encryption.value ?? {
|
|
682
|
+
mode: null,
|
|
683
|
+
algorithm: null
|
|
684
|
+
};
|
|
685
|
+
}
|
|
444
686
|
function customerKeyDigest(customerKey) {
|
|
445
687
|
let first = 2166136261;
|
|
446
688
|
let second = 668265261;
|
|
@@ -495,13 +737,21 @@ function hasCustomerEncryptionFields(encryption) {
|
|
|
495
737
|
function hasCustomerEncryptionHeaders(headers) {
|
|
496
738
|
return headers["x-bz-server-side-encryption-customer-algorithm"] !== void 0 || headers["x-bz-server-side-encryption-customer-key"] !== void 0 || headers["x-bz-server-side-encryption-customer-key-md5"] !== void 0;
|
|
497
739
|
}
|
|
740
|
+
function isExactNoEncryptionWireSetting(encryption) {
|
|
741
|
+
return encryption["mode"] === null && encryption["algorithm"] === null && Object.keys(encryption).length === 2;
|
|
742
|
+
}
|
|
498
743
|
async function storedServerSideEncryption(encryption) {
|
|
499
744
|
const runtimeEncryption = encryption;
|
|
745
|
+
if (encryption.mode === null) {
|
|
746
|
+
if (isExactNoEncryptionWireSetting(runtimeEncryption)) return { mode: require_encryption.EncryptionMode.None };
|
|
747
|
+
if (hasCustomerEncryptionFields(runtimeEncryption)) return encryptionValidationError("No-encryption settings must not include SSE-C customer keys");
|
|
748
|
+
return encryptionValidationError("No-encryption wire settings must be exactly { mode: null, algorithm: null }");
|
|
749
|
+
}
|
|
500
750
|
if (encryption.mode === require_encryption.EncryptionMode.SseC) {
|
|
501
751
|
if (runtimeEncryption["algorithm"] === void 0) return encryptionValidationError("SSE-C customer algorithm is required");
|
|
502
752
|
if (encryption.algorithm !== require_encryption.EncryptionAlgorithm.Aes256) return encryptionValidationError("SSE-C customer algorithm must be AES256");
|
|
503
|
-
const customerKey = encryption.customerKey;
|
|
504
|
-
const customerKeyMd5 = encryption.customerKeyMd5;
|
|
753
|
+
const customerKey = "customerKey" in encryption ? encryption.customerKey : void 0;
|
|
754
|
+
const customerKeyMd5 = "customerKeyMd5" in encryption ? encryption.customerKeyMd5 : void 0;
|
|
505
755
|
if (typeof customerKey !== "string" || customerKey === "") return encryptionValidationError("SSE-C customer key is required");
|
|
506
756
|
if (typeof customerKeyMd5 !== "string" || customerKeyMd5 === "") return encryptionValidationError("SSE-C customer key MD5 is required");
|
|
507
757
|
const customerKeyBytes = base64ToBytes(customerKey, 32);
|
|
@@ -556,7 +806,22 @@ async function uploadServerSideEncryption(headers, fallback) {
|
|
|
556
806
|
}
|
|
557
807
|
return await storedServerSideEncryption(fallback);
|
|
558
808
|
}
|
|
809
|
+
function noBucketDefaultRetention() {
|
|
810
|
+
return {
|
|
811
|
+
mode: null,
|
|
812
|
+
period: null
|
|
813
|
+
};
|
|
814
|
+
}
|
|
815
|
+
function bucketDefaultRetentionForResponse(policy) {
|
|
816
|
+
if (policy === void 0 || policy.mode === require_bucket.BucketRetentionMode.None) return noBucketDefaultRetention();
|
|
817
|
+
return policy;
|
|
818
|
+
}
|
|
819
|
+
function bucketDefaultRetention(info) {
|
|
820
|
+
return info.fileLockConfiguration.value?.defaultRetention;
|
|
821
|
+
}
|
|
559
822
|
function defaultFileRetention(policy, uploadTimestamp) {
|
|
823
|
+
if (policy === void 0) return null;
|
|
824
|
+
if (policy.mode === null) return null;
|
|
560
825
|
if (policy.mode === require_bucket.BucketRetentionMode.None || policy.period === null) return null;
|
|
561
826
|
const retainUntilTimestamp = uploadTimestamp + (policy.period.unit === "days" ? policy.period.duration : policy.period.duration * 365) * MS_PER_DAY;
|
|
562
827
|
if (!isValidRetentionTimestamp(retainUntilTimestamp, uploadTimestamp)) return null;
|
|
@@ -1025,6 +1290,16 @@ var B2Simulator = class {
|
|
|
1025
1290
|
if (authToken === void 0) return false;
|
|
1026
1291
|
return this.issuedTokens.get(authToken)?.capabilities.includes(capability) === true;
|
|
1027
1292
|
}
|
|
1293
|
+
bucketInfoForResponse(info, authToken) {
|
|
1294
|
+
return {
|
|
1295
|
+
...info,
|
|
1296
|
+
defaultServerSideEncryption: this.requestHasCapability(authToken, require_auth.Capability.ReadBucketEncryption) ? info.defaultServerSideEncryption : {
|
|
1297
|
+
isClientAuthorizedToRead: false,
|
|
1298
|
+
value: null
|
|
1299
|
+
},
|
|
1300
|
+
replicationConfiguration: filterReadableReplicationConfiguration(info.replicationConfiguration, this.requestHasCapability(authToken, require_auth.Capability.ReadBucketReplications))
|
|
1301
|
+
};
|
|
1302
|
+
}
|
|
1028
1303
|
requireFileLockEnabled(bucket) {
|
|
1029
1304
|
if (bucket.info.fileLockConfiguration.value?.isFileLockEnabled === true) return null;
|
|
1030
1305
|
return this.error(400, "file_lock_not_enabled", "Bucket does not have file lock enabled");
|
|
@@ -1051,7 +1326,7 @@ var B2Simulator = class {
|
|
|
1051
1326
|
for (const rule of rules) {
|
|
1052
1327
|
const destinationBucketId = requestRecord(rule)?.["destinationBucketId"];
|
|
1053
1328
|
if (typeof destinationBucketId !== "string") continue;
|
|
1054
|
-
const destinationApplicationKeyId = this.buckets.get(destinationBucketId)?.info.replicationConfiguration.asReplicationDestination?.sourceToDestinationKeyMapping[sourceApplicationKeyId];
|
|
1329
|
+
const destinationApplicationKeyId = this.buckets.get(destinationBucketId)?.info.replicationConfiguration.value?.asReplicationDestination?.sourceToDestinationKeyMapping[sourceApplicationKeyId];
|
|
1055
1330
|
if (destinationApplicationKeyId === void 0) return this.invalidReplicationDestinationBucket();
|
|
1056
1331
|
const destinationKeyError = this.validateReplicationApplicationKey(destinationApplicationKeyId, [require_auth.Capability.WriteFiles], {
|
|
1057
1332
|
bucketId: destinationBucketId,
|
|
@@ -1480,7 +1755,8 @@ var B2Simulator = class {
|
|
|
1480
1755
|
* @returns An object with HTTP status and JSON response body.
|
|
1481
1756
|
*/
|
|
1482
1757
|
async handleRequest(method, origin, path, headers, body) {
|
|
1483
|
-
const { endpoint, version } = apiPathParts(path);
|
|
1758
|
+
const { endpoint, version, unsupportedVersion } = apiPathParts(path);
|
|
1759
|
+
if (unsupportedVersion !== void 0) return this.error(400, "unsupported_api_version", `B2 API version ${unsupportedVersion} is not supported by the simulator; use v4 or v3`);
|
|
1484
1760
|
if (!jsonEndpointAllowsMethod(method, endpoint)) return this.error(405, "method_not_allowed", `${endpoint} does not support ${method.toUpperCase()}`);
|
|
1485
1761
|
if (this.strictAuth && !this.partner.isEndpoint(endpoint)) {
|
|
1486
1762
|
const authError = this.authorizeRequest(headers["authorization"], endpoint, this.requestScope(endpoint, body));
|
|
@@ -1490,17 +1766,17 @@ var B2Simulator = class {
|
|
|
1490
1766
|
case "b2_authorize_account":
|
|
1491
1767
|
if (version === "v3" && this.partner.isAuthorizeEnabled()) return this.partner.authorize(headers["authorization"], origin);
|
|
1492
1768
|
return this.authorize(headers["authorization"], origin);
|
|
1493
|
-
case
|
|
1494
|
-
case
|
|
1495
|
-
case
|
|
1496
|
-
case
|
|
1497
|
-
case
|
|
1498
|
-
case
|
|
1499
|
-
case
|
|
1500
|
-
case "b2_create_bucket": return this.createBucket(body);
|
|
1501
|
-
case "b2_list_buckets": return this.listBuckets(body);
|
|
1502
|
-
case "b2_delete_bucket": return this.deleteBucket(body);
|
|
1503
|
-
case "b2_update_bucket": return this.updateBucket(body);
|
|
1769
|
+
case require_partner_capabilities.PartnerEndpoint.CreateGroupMember: return this.partner.createGroupMember(body, headers["authorization"]);
|
|
1770
|
+
case require_partner_capabilities.PartnerEndpoint.EjectGroupMember: return this.partner.ejectGroupMember(body, headers["authorization"]);
|
|
1771
|
+
case require_partner_capabilities.PartnerEndpoint.ListGroups: return this.partner.listGroups(body, headers["authorization"]);
|
|
1772
|
+
case require_partner_capabilities.PartnerEndpoint.ListGroupMembers: return this.partner.listGroupMembers(body, headers["authorization"]);
|
|
1773
|
+
case require_partner_capabilities.PartnerEndpoint.ReserveTrialCreateAccount: return this.partner.reserveTrialCreateAccount(body, headers["authorization"]);
|
|
1774
|
+
case require_partner_capabilities.PartnerEndpoint.ListComputers: return this.partner.listComputers(body, headers["authorization"]);
|
|
1775
|
+
case require_partner_capabilities.PartnerEndpoint.DeleteComputer: return this.partner.deleteComputer(body, headers["authorization"]);
|
|
1776
|
+
case "b2_create_bucket": return this.createBucket(body, headers["authorization"]);
|
|
1777
|
+
case "b2_list_buckets": return this.listBuckets(body, headers["authorization"]);
|
|
1778
|
+
case "b2_delete_bucket": return this.deleteBucket(body, headers["authorization"]);
|
|
1779
|
+
case "b2_update_bucket": return this.updateBucket(body, headers["authorization"]);
|
|
1504
1780
|
case "b2_get_upload_url": return await this.getUploadUrl(body, headers["authorization"]);
|
|
1505
1781
|
case "b2_list_file_names": return this.listFileNames(body);
|
|
1506
1782
|
case "b2_list_file_versions": return this.listFileVersions(body);
|
|
@@ -1508,11 +1784,11 @@ var B2Simulator = class {
|
|
|
1508
1784
|
case "b2_hide_file": return this.hideFile(body);
|
|
1509
1785
|
case "b2_delete_file_version": return this.deleteFileVersion(body, headers["authorization"]);
|
|
1510
1786
|
case "b2_copy_file": return await this.copyFile(body);
|
|
1511
|
-
case "b2_start_large_file": return await this.startLargeFile(body);
|
|
1787
|
+
case "b2_start_large_file": return await this.startLargeFile(body, headers["authorization"]);
|
|
1512
1788
|
case "b2_get_upload_part_url": return await this.getUploadPartUrl(body, headers["authorization"]);
|
|
1513
1789
|
case "b2_finish_large_file": return this.finishLargeFile(body);
|
|
1514
1790
|
case "b2_cancel_large_file": return this.cancelLargeFile(body);
|
|
1515
|
-
case "b2_list_unfinished_large_files": return this.listUnfinishedLargeFiles(body);
|
|
1791
|
+
case "b2_list_unfinished_large_files": return this.listUnfinishedLargeFiles(body, headers["authorization"]);
|
|
1516
1792
|
case "b2_list_parts": return this.listParts(body);
|
|
1517
1793
|
case "b2_copy_part": return await this.copyPart(body);
|
|
1518
1794
|
case "b2_get_download_authorization": return this.getDownloadAuthorization(body);
|
|
@@ -1668,7 +1944,7 @@ var B2Simulator = class {
|
|
|
1668
1944
|
const resolved = await this.resolveUploadSha1(headers["x-bz-content-sha1"], data);
|
|
1669
1945
|
if ("status" in resolved) return resolved;
|
|
1670
1946
|
const { sha1: contentSha1, data: storedData } = resolved;
|
|
1671
|
-
const serverSideEncryption = await uploadServerSideEncryption(headers, bucket.info
|
|
1947
|
+
const serverSideEncryption = await uploadServerSideEncryption(headers, bucketDefaultServerSideEncryptionForStorage(bucket.info));
|
|
1672
1948
|
if ("status" in serverSideEncryption) return serverSideEncryption;
|
|
1673
1949
|
const customUploadTimestamp = this.parseCustomUploadTimestamp(requestHeaderValue(headers, "x-bz-custom-upload-timestamp"));
|
|
1674
1950
|
if ("status" in customUploadTimestamp) return customUploadTimestamp;
|
|
@@ -1845,7 +2121,7 @@ var B2Simulator = class {
|
|
|
1845
2121
|
}
|
|
1846
2122
|
async resolveCopyDestinationEncryption(destinationBucket, requested) {
|
|
1847
2123
|
if (requested !== void 0) return await storedServerSideEncryption(requested);
|
|
1848
|
-
return await storedServerSideEncryption(destinationBucket.info
|
|
2124
|
+
return await storedServerSideEncryption(bucketDefaultServerSideEncryptionForStorage(destinationBucket.info));
|
|
1849
2125
|
}
|
|
1850
2126
|
async validateCopyPartDestinationEncryption(large, encryption) {
|
|
1851
2127
|
if (encryption === void 0) return large.serverSideEncryption.mode === require_encryption.EncryptionMode.SseC ? this.error(400, "bad_request", "SSE-C destination copies require customer encryption") : null;
|
|
@@ -1973,9 +2249,11 @@ var B2Simulator = class {
|
|
|
1973
2249
|
}
|
|
1974
2250
|
};
|
|
1975
2251
|
}
|
|
1976
|
-
createBucket(req) {
|
|
2252
|
+
createBucket(req, authToken) {
|
|
1977
2253
|
const nameError = require_validation.validateBucketName(req.bucketName);
|
|
1978
2254
|
if (nameError) return this.error(400, nameError.code, nameError.message);
|
|
2255
|
+
const bucketTypeError = require_validation.validateBucketType(req.bucketType);
|
|
2256
|
+
if (bucketTypeError) return this.error(400, bucketTypeError.code, bucketTypeError.message);
|
|
1979
2257
|
const objectLockEnabled = nextObjectLockEnabled(false, req.fileLockEnabled);
|
|
1980
2258
|
if (typeof objectLockEnabled !== "boolean") return this.error(400, objectLockEnabled.code, objectLockEnabled.message);
|
|
1981
2259
|
const configError = validateBucketConfigurationFields(req, { objectLockEnabled });
|
|
@@ -1984,10 +2262,7 @@ var B2Simulator = class {
|
|
|
1984
2262
|
if (replicationKeyError !== null) return replicationKeyError;
|
|
1985
2263
|
for (const b of this.buckets.values()) if (b.info.bucketName === req.bucketName) return this.error(400, "duplicate_bucket_name", "Bucket name already in use");
|
|
1986
2264
|
const bid = require_ids.bucketId(this.genId("b2_bucket"));
|
|
1987
|
-
const defaultRetention = req.defaultRetention
|
|
1988
|
-
mode: require_bucket.BucketRetentionMode.None,
|
|
1989
|
-
period: null
|
|
1990
|
-
};
|
|
2265
|
+
const defaultRetention = bucketDefaultRetentionForResponse(req.defaultRetention);
|
|
1991
2266
|
const info = {
|
|
1992
2267
|
accountId: require_ids.accountId(req.accountId),
|
|
1993
2268
|
bucketId: bid,
|
|
@@ -1995,7 +2270,7 @@ var B2Simulator = class {
|
|
|
1995
2270
|
bucketType: req.bucketType,
|
|
1996
2271
|
bucketInfo: req.bucketInfo ?? {},
|
|
1997
2272
|
corsRules: req.corsRules ?? [],
|
|
1998
|
-
defaultServerSideEncryption: req.defaultServerSideEncryption
|
|
2273
|
+
defaultServerSideEncryption: publicBucketDefaultServerSideEncryption(req.defaultServerSideEncryption),
|
|
1999
2274
|
fileLockConfiguration: {
|
|
2000
2275
|
isClientAuthorizedToRead: true,
|
|
2001
2276
|
value: {
|
|
@@ -2006,11 +2281,7 @@ var B2Simulator = class {
|
|
|
2006
2281
|
lifecycleRules: req.lifecycleRules ?? [],
|
|
2007
2282
|
options: [],
|
|
2008
2283
|
revision: 1,
|
|
2009
|
-
|
|
2010
|
-
replicationConfiguration: req.replicationConfiguration === void 0 ? {
|
|
2011
|
-
asReplicationSource: null,
|
|
2012
|
-
asReplicationDestination: null
|
|
2013
|
-
} : normalizeReplicationConfiguration(req.replicationConfiguration)
|
|
2284
|
+
replicationConfiguration: wrapReplicationConfiguration(req.replicationConfiguration)
|
|
2014
2285
|
};
|
|
2015
2286
|
this.buckets.set(bid, {
|
|
2016
2287
|
info,
|
|
@@ -2018,25 +2289,25 @@ var B2Simulator = class {
|
|
|
2018
2289
|
});
|
|
2019
2290
|
return {
|
|
2020
2291
|
status: 200,
|
|
2021
|
-
body: info
|
|
2292
|
+
body: this.bucketInfoForResponse(info, authToken)
|
|
2022
2293
|
};
|
|
2023
2294
|
}
|
|
2024
|
-
listBuckets(req) {
|
|
2295
|
+
listBuckets(req, authToken) {
|
|
2025
2296
|
const bucketTypesError = require_validation.validateBucketTypes(req.bucketTypes);
|
|
2026
2297
|
if (bucketTypesError) return this.error(400, bucketTypesError.code, bucketTypesError.message);
|
|
2027
2298
|
return {
|
|
2028
2299
|
status: 200,
|
|
2029
|
-
body: { buckets: [...this.buckets.values()].map((b) => b.info).filter((bucket) => req.bucketId === void 0 || bucket.bucketId === req.bucketId).filter((bucket) => req.bucketName === void 0 || bucket.bucketName === req.bucketName).filter((bucket) => req.bucketTypes === void 0 || req.bucketTypes.
|
|
2300
|
+
body: { buckets: [...this.buckets.values()].map((b) => b.info).filter((bucket) => req.bucketId === void 0 || bucket.bucketId === req.bucketId).filter((bucket) => req.bucketName === void 0 || bucket.bucketName === req.bucketName).filter((bucket) => req.bucketTypes === void 0 || req.bucketTypes[0] === "all" || req.bucketTypes.some((bucketType) => bucketType === bucket.bucketType)).map((bucket) => this.bucketInfoForResponse(bucket, authToken)) }
|
|
2030
2301
|
};
|
|
2031
2302
|
}
|
|
2032
|
-
deleteBucket(req) {
|
|
2303
|
+
deleteBucket(req, authToken) {
|
|
2033
2304
|
const bucket = this.buckets.get(req.bucketId);
|
|
2034
2305
|
if (!bucket) return this.error(400, "bad_bucket_id", "Bucket not found");
|
|
2035
2306
|
if (this.bucketHasContents(bucket)) return this.error(400, "cannot_delete_non_empty_bucket", "Bucket is not empty and cannot be deleted");
|
|
2036
2307
|
this.buckets.delete(req.bucketId);
|
|
2037
2308
|
return {
|
|
2038
2309
|
status: 200,
|
|
2039
|
-
body: bucket.info
|
|
2310
|
+
body: this.bucketInfoForResponse(bucket.info, authToken)
|
|
2040
2311
|
};
|
|
2041
2312
|
}
|
|
2042
2313
|
bucketHasContents(bucket) {
|
|
@@ -2044,7 +2315,7 @@ var B2Simulator = class {
|
|
|
2044
2315
|
for (const large of this.largeFiles.values()) if (large.bucketId === bucket.info.bucketId) return true;
|
|
2045
2316
|
return false;
|
|
2046
2317
|
}
|
|
2047
|
-
updateBucket(req) {
|
|
2318
|
+
updateBucket(req, authToken) {
|
|
2048
2319
|
const bucket = this.buckets.get(req["bucketId"]);
|
|
2049
2320
|
if (!bucket) return this.error(400, "bad_bucket_id", "Bucket not found");
|
|
2050
2321
|
const revisionGuard = req["ifRevisionIs"];
|
|
@@ -2054,9 +2325,14 @@ var B2Simulator = class {
|
|
|
2054
2325
|
}
|
|
2055
2326
|
const objectLockEnabled = nextObjectLockEnabled(bucket.info.fileLockConfiguration.value?.isFileLockEnabled ?? false, req["fileLockEnabled"]);
|
|
2056
2327
|
if (typeof objectLockEnabled !== "boolean") return this.error(400, objectLockEnabled.code, objectLockEnabled.message);
|
|
2328
|
+
if (req["bucketType"] !== void 0) {
|
|
2329
|
+
const bucketTypeError = require_validation.validateBucketType(req["bucketType"]);
|
|
2330
|
+
if (bucketTypeError) return this.error(400, bucketTypeError.code, bucketTypeError.message);
|
|
2331
|
+
}
|
|
2057
2332
|
const configError = validateBucketConfigurationFields({
|
|
2058
2333
|
bucketInfo: req["bucketInfo"],
|
|
2059
2334
|
corsRules: req["corsRules"],
|
|
2335
|
+
defaultServerSideEncryption: req["defaultServerSideEncryption"],
|
|
2060
2336
|
defaultRetention: req["defaultRetention"],
|
|
2061
2337
|
lifecycleRules: req["lifecycleRules"],
|
|
2062
2338
|
replicationConfiguration: req["replicationConfiguration"]
|
|
@@ -2070,25 +2346,22 @@ var B2Simulator = class {
|
|
|
2070
2346
|
...req["bucketInfo"] !== void 0 ? { bucketInfo: req["bucketInfo"] } : {},
|
|
2071
2347
|
...req["lifecycleRules"] !== void 0 ? { lifecycleRules: req["lifecycleRules"] } : {},
|
|
2072
2348
|
...req["corsRules"] !== void 0 ? { corsRules: req["corsRules"] } : {},
|
|
2073
|
-
...req["replicationConfiguration"] !== void 0 ? { replicationConfiguration:
|
|
2074
|
-
...req["defaultRetention"] !== void 0 ? {
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
isFileLockEnabled: objectLockEnabled,
|
|
2080
|
-
defaultRetention: req["defaultRetention"]
|
|
2081
|
-
}
|
|
2349
|
+
...req["replicationConfiguration"] !== void 0 ? { replicationConfiguration: wrapReplicationConfiguration(req["replicationConfiguration"]) } : {},
|
|
2350
|
+
...req["defaultRetention"] !== void 0 ? { fileLockConfiguration: {
|
|
2351
|
+
isClientAuthorizedToRead: true,
|
|
2352
|
+
value: {
|
|
2353
|
+
isFileLockEnabled: objectLockEnabled,
|
|
2354
|
+
defaultRetention: bucketDefaultRetentionForResponse(req["defaultRetention"])
|
|
2082
2355
|
}
|
|
2083
|
-
} : {},
|
|
2356
|
+
} } : {},
|
|
2084
2357
|
...req["fileLockEnabled"] !== void 0 && req["defaultRetention"] === void 0 ? { fileLockConfiguration: {
|
|
2085
2358
|
isClientAuthorizedToRead: true,
|
|
2086
2359
|
value: {
|
|
2087
2360
|
isFileLockEnabled: objectLockEnabled,
|
|
2088
|
-
defaultRetention: bucket.info
|
|
2361
|
+
defaultRetention: bucketDefaultRetention(bucket.info) ?? noBucketDefaultRetention()
|
|
2089
2362
|
}
|
|
2090
2363
|
} } : {},
|
|
2091
|
-
...req["defaultServerSideEncryption"] !== void 0 ? { defaultServerSideEncryption: req["defaultServerSideEncryption"] } : {},
|
|
2364
|
+
...req["defaultServerSideEncryption"] !== void 0 ? { defaultServerSideEncryption: publicBucketDefaultServerSideEncryption(req["defaultServerSideEncryption"]) } : {},
|
|
2092
2365
|
revision: bucket.info.revision + 1
|
|
2093
2366
|
};
|
|
2094
2367
|
this.buckets.set(req["bucketId"], {
|
|
@@ -2097,7 +2370,7 @@ var B2Simulator = class {
|
|
|
2097
2370
|
});
|
|
2098
2371
|
return {
|
|
2099
2372
|
status: 200,
|
|
2100
|
-
body: updated
|
|
2373
|
+
body: this.bucketInfoForResponse(updated, authToken)
|
|
2101
2374
|
};
|
|
2102
2375
|
}
|
|
2103
2376
|
async getUploadUrl(req, authToken) {
|
|
@@ -2123,7 +2396,13 @@ var B2Simulator = class {
|
|
|
2123
2396
|
if (countError) return this.error(400, countError.code, countError.message);
|
|
2124
2397
|
const max = req.maxFileCount ?? 1e3;
|
|
2125
2398
|
const prefix = req.prefix ?? "";
|
|
2126
|
-
|
|
2399
|
+
const currentVersions = [...bucket.files.entries()].filter(([name]) => name.startsWith(prefix)).map(([_, versions]) => versions[versions.length - 1]).filter((v) => v !== void 0).map((v) => v.fileVersion).filter((v) => v.action !== require_file.FileAction.Hide).sort((a, b) => compareB2FileNames(a.fileName, b.fileName));
|
|
2400
|
+
let allFiles = this.applyListDelimiter({
|
|
2401
|
+
bucketId: req.bucketId,
|
|
2402
|
+
delimiter: req.delimiter,
|
|
2403
|
+
entries: currentVersions,
|
|
2404
|
+
prefix
|
|
2405
|
+
});
|
|
2127
2406
|
if (req.startFileName) {
|
|
2128
2407
|
const start = req.startFileName;
|
|
2129
2408
|
allFiles = allFiles.filter((f) => f.fileName >= start);
|
|
@@ -2143,11 +2422,17 @@ var B2Simulator = class {
|
|
|
2143
2422
|
if (countError) return this.error(400, countError.code, countError.message);
|
|
2144
2423
|
const max = req.maxFileCount ?? 1e3;
|
|
2145
2424
|
const prefix = req.prefix ?? "";
|
|
2146
|
-
const
|
|
2425
|
+
const versions = [...bucket.files.entries()].filter(([name]) => name.startsWith(prefix)).flatMap(([_, versions]) => versions.map((v) => v.fileVersion)).sort((a, b) => {
|
|
2147
2426
|
const nameCmp = compareB2FileNames(a.fileName, b.fileName);
|
|
2148
2427
|
if (nameCmp !== 0) return nameCmp;
|
|
2149
2428
|
return b.uploadTimestamp - a.uploadTimestamp;
|
|
2150
2429
|
});
|
|
2430
|
+
const allVersions = this.applyListDelimiter({
|
|
2431
|
+
bucketId: req.bucketId,
|
|
2432
|
+
delimiter: req.delimiter,
|
|
2433
|
+
entries: versions,
|
|
2434
|
+
prefix
|
|
2435
|
+
});
|
|
2151
2436
|
let startIdx = 0;
|
|
2152
2437
|
if (req.startFileName !== void 0) {
|
|
2153
2438
|
const startName = req.startFileName;
|
|
@@ -2170,6 +2455,48 @@ var B2Simulator = class {
|
|
|
2170
2455
|
}
|
|
2171
2456
|
};
|
|
2172
2457
|
}
|
|
2458
|
+
applyListDelimiter(params) {
|
|
2459
|
+
if (params.delimiter === void 0 || params.delimiter === "") return params.entries.map((entry) => this.toListEntry(entry));
|
|
2460
|
+
const grouped = [];
|
|
2461
|
+
const seenFolders = /* @__PURE__ */ new Set();
|
|
2462
|
+
for (const entry of params.entries) {
|
|
2463
|
+
const delimiterIndex = entry.fileName.indexOf(params.delimiter, params.prefix.length);
|
|
2464
|
+
if (delimiterIndex === -1) {
|
|
2465
|
+
grouped.push(this.toListEntry(entry));
|
|
2466
|
+
continue;
|
|
2467
|
+
}
|
|
2468
|
+
const folderName = entry.fileName.slice(0, delimiterIndex + params.delimiter.length);
|
|
2469
|
+
if (!seenFolders.has(folderName)) {
|
|
2470
|
+
seenFolders.add(folderName);
|
|
2471
|
+
grouped.push(this.makeFolderListEntry(params.bucketId, folderName));
|
|
2472
|
+
}
|
|
2473
|
+
}
|
|
2474
|
+
return grouped.sort(compareFileVersionListEntries);
|
|
2475
|
+
}
|
|
2476
|
+
toListEntry(entry) {
|
|
2477
|
+
if (entry.action !== require_file.FileAction.Hide) return entry;
|
|
2478
|
+
const { contentType: _contentType, fileRetention, legalHold, serverSideEncryption, ...listed } = entry;
|
|
2479
|
+
return {
|
|
2480
|
+
...listed,
|
|
2481
|
+
action: require_file.FileAction.Hide,
|
|
2482
|
+
contentType: require_file.HIDE_MARKER_CONTENT_TYPE
|
|
2483
|
+
};
|
|
2484
|
+
}
|
|
2485
|
+
makeFolderListEntry(bucketId$1, fileName) {
|
|
2486
|
+
return {
|
|
2487
|
+
accountId: require_ids.accountId(this.accountId),
|
|
2488
|
+
action: require_file.FileAction.Folder,
|
|
2489
|
+
bucketId: require_ids.bucketId(bucketId$1),
|
|
2490
|
+
contentLength: 0,
|
|
2491
|
+
contentMd5: null,
|
|
2492
|
+
contentSha1: null,
|
|
2493
|
+
contentType: null,
|
|
2494
|
+
fileId: null,
|
|
2495
|
+
fileInfo: {},
|
|
2496
|
+
fileName,
|
|
2497
|
+
uploadTimestamp: 0
|
|
2498
|
+
};
|
|
2499
|
+
}
|
|
2173
2500
|
getFileInfo(req) {
|
|
2174
2501
|
const found = this.findFile(req.fileId);
|
|
2175
2502
|
if (found === null) return this.error(404, "file_not_present", "File not found");
|
|
@@ -2186,7 +2513,7 @@ var B2Simulator = class {
|
|
|
2186
2513
|
const fileVersion = this.makeFileVersion({
|
|
2187
2514
|
bucketId: req.bucketId,
|
|
2188
2515
|
fileName: req.fileName,
|
|
2189
|
-
contentType:
|
|
2516
|
+
contentType: require_file.HIDE_MARKER_CONTENT_TYPE,
|
|
2190
2517
|
contentLength: 0,
|
|
2191
2518
|
contentSha1: "none",
|
|
2192
2519
|
action: require_file.FileAction.Hide
|
|
@@ -2290,7 +2617,7 @@ var B2Simulator = class {
|
|
|
2290
2617
|
body: fileVersion
|
|
2291
2618
|
};
|
|
2292
2619
|
}
|
|
2293
|
-
async startLargeFile(req) {
|
|
2620
|
+
async startLargeFile(req, authToken) {
|
|
2294
2621
|
const bucket = this.buckets.get(req.bucketId);
|
|
2295
2622
|
if (!bucket) return this.error(400, "bad_bucket_id", "Bucket not found");
|
|
2296
2623
|
const nameError = require_validation.validateFileName(req.fileName);
|
|
@@ -2303,7 +2630,7 @@ var B2Simulator = class {
|
|
|
2303
2630
|
if ("status" in customUploadTimestamp) return customUploadTimestamp;
|
|
2304
2631
|
const fid = this.genId("4_z");
|
|
2305
2632
|
const uploadTimestamp = customUploadTimestamp.timestamp ?? this.monotonicTimestamp();
|
|
2306
|
-
const serverSideEncryption = await storedServerSideEncryption(req.serverSideEncryption ?? bucket.info
|
|
2633
|
+
const serverSideEncryption = await storedServerSideEncryption(req.serverSideEncryption ?? bucketDefaultServerSideEncryptionForStorage(bucket.info));
|
|
2307
2634
|
if ("status" in serverSideEncryption) return serverSideEncryption;
|
|
2308
2635
|
const replicationStatus = this.replicationStatusForNewFile(req.bucketId, req.fileName);
|
|
2309
2636
|
const large = {
|
|
@@ -2312,7 +2639,7 @@ var B2Simulator = class {
|
|
|
2312
2639
|
fileName: req.fileName,
|
|
2313
2640
|
contentType: req.contentType,
|
|
2314
2641
|
fileInfo: req.fileInfo ?? {},
|
|
2315
|
-
fileRetention: req.fileRetention ?? defaultFileRetention(bucket.info
|
|
2642
|
+
fileRetention: req.fileRetention ?? defaultFileRetention(bucketDefaultRetention(bucket.info), uploadTimestamp),
|
|
2316
2643
|
legalHold: req.legalHold ?? null,
|
|
2317
2644
|
...this.replicationStatusMetadataFor(replicationStatus),
|
|
2318
2645
|
serverSideEncryption,
|
|
@@ -2333,14 +2660,8 @@ var B2Simulator = class {
|
|
|
2333
2660
|
contentLength: 0,
|
|
2334
2661
|
contentSha1: "none",
|
|
2335
2662
|
contentMd5: null,
|
|
2336
|
-
fileRetention:
|
|
2337
|
-
|
|
2338
|
-
value: large.fileRetention
|
|
2339
|
-
},
|
|
2340
|
-
legalHold: {
|
|
2341
|
-
isClientAuthorizedToRead: true,
|
|
2342
|
-
value: large.legalHold
|
|
2343
|
-
},
|
|
2663
|
+
fileRetention: readableFileRetention(large.fileRetention, this.requestHasCapability(authToken, require_auth.Capability.ReadFileRetentions)),
|
|
2664
|
+
legalHold: readableLegalHold(large.legalHold, this.requestHasCapability(authToken, require_auth.Capability.ReadFileLegalHolds)),
|
|
2344
2665
|
...this.replicationStatusMetadataFor(large.replicationStatus),
|
|
2345
2666
|
serverSideEncryption: publicServerSideEncryption(large.serverSideEncryption),
|
|
2346
2667
|
uploadTimestamp: large.uploadTimestamp
|
|
@@ -2427,7 +2748,7 @@ var B2Simulator = class {
|
|
|
2427
2748
|
}
|
|
2428
2749
|
};
|
|
2429
2750
|
}
|
|
2430
|
-
listUnfinishedLargeFiles(req) {
|
|
2751
|
+
listUnfinishedLargeFiles(req, authToken) {
|
|
2431
2752
|
const countError = require_validation.validateMaxCount(req.maxFileCount, "b2_list_unfinished_large_files");
|
|
2432
2753
|
if (countError) return this.error(400, countError.code, countError.message);
|
|
2433
2754
|
const prefix = req.namePrefix ?? "";
|
|
@@ -2438,10 +2759,13 @@ var B2Simulator = class {
|
|
|
2438
2759
|
const found = candidates.findIndex((f) => f.fileId === req.startFileId);
|
|
2439
2760
|
startIndex = found >= 0 ? found : 0;
|
|
2440
2761
|
}
|
|
2762
|
+
const slice = candidates.slice(startIndex, startIndex + max);
|
|
2763
|
+
const canReadFileRetentions = this.requestHasCapability(authToken, require_auth.Capability.ReadFileRetentions);
|
|
2764
|
+
const canReadFileLegalHolds = this.requestHasCapability(authToken, require_auth.Capability.ReadFileLegalHolds);
|
|
2441
2765
|
return {
|
|
2442
2766
|
status: 200,
|
|
2443
2767
|
body: {
|
|
2444
|
-
files:
|
|
2768
|
+
files: slice.map((f) => ({
|
|
2445
2769
|
fileId: f.fileId,
|
|
2446
2770
|
fileName: f.fileName,
|
|
2447
2771
|
accountId: this.accountId,
|
|
@@ -2452,14 +2776,8 @@ var B2Simulator = class {
|
|
|
2452
2776
|
contentSha1: "none",
|
|
2453
2777
|
contentMd5: null,
|
|
2454
2778
|
fileInfo: f.fileInfo,
|
|
2455
|
-
fileRetention:
|
|
2456
|
-
|
|
2457
|
-
value: f.fileRetention
|
|
2458
|
-
},
|
|
2459
|
-
legalHold: {
|
|
2460
|
-
isClientAuthorizedToRead: true,
|
|
2461
|
-
value: f.legalHold
|
|
2462
|
-
},
|
|
2779
|
+
fileRetention: readableFileRetention(f.fileRetention, canReadFileRetentions),
|
|
2780
|
+
legalHold: readableLegalHold(f.legalHold, canReadFileLegalHolds),
|
|
2463
2781
|
...this.replicationStatusMetadataFor(f.replicationStatus),
|
|
2464
2782
|
serverSideEncryption: publicServerSideEncryption(f.serverSideEncryption),
|
|
2465
2783
|
uploadTimestamp: f.uploadTimestamp
|
|
@@ -2814,7 +3132,7 @@ var B2Simulator = class {
|
|
|
2814
3132
|
return this.matchingEnabledReplicationRules(bucketId, fileName).length > 0 ? "PENDING" : void 0;
|
|
2815
3133
|
}
|
|
2816
3134
|
matchingEnabledReplicationRules(bucketId, fileName) {
|
|
2817
|
-
return (this.buckets.get(bucketId)?.info.replicationConfiguration.asReplicationSource?.replicationRules)?.filter((rule) => rule.isEnabled && fileName.startsWith(rule.fileNamePrefix)) ?? [];
|
|
3135
|
+
return (this.buckets.get(bucketId)?.info.replicationConfiguration.value?.asReplicationSource?.replicationRules)?.filter((rule) => rule.isEnabled && fileName.startsWith(rule.fileNamePrefix)) ?? [];
|
|
2818
3136
|
}
|
|
2819
3137
|
error(status, code, message) {
|
|
2820
3138
|
return {
|
|
@@ -3083,6 +3401,7 @@ var SimulatorTransport = class {
|
|
|
3083
3401
|
result = "error" in uploadBody ? uploadBody.error : await this.sim.handleUpload(url, headers, uploadBody.data);
|
|
3084
3402
|
}
|
|
3085
3403
|
} else {
|
|
3404
|
+
const requestPath = apiPathParts(parsedUrl.pathname);
|
|
3086
3405
|
let body = null;
|
|
3087
3406
|
if (request.body) {
|
|
3088
3407
|
const text = typeof request.body === "string" ? request.body : await new Response(request.body).text();
|
|
@@ -3091,7 +3410,7 @@ var SimulatorTransport = class {
|
|
|
3091
3410
|
} catch {
|
|
3092
3411
|
body = text;
|
|
3093
3412
|
}
|
|
3094
|
-
} else if (request.method.toUpperCase() === "GET" &&
|
|
3413
|
+
} else if (request.method.toUpperCase() === "GET" && isJsonQueryEndpoint(requestPath.endpoint)) body = queryParamsBody(parsedUrl.searchParams, requestPath.endpoint);
|
|
3095
3414
|
result = await this.sim.handleRequest(request.method, parsedUrl.origin, parsedUrl.pathname, headers, body);
|
|
3096
3415
|
}
|
|
3097
3416
|
const responseBody = JSON.stringify(result.body);
|
|
@@ -3110,10 +3429,22 @@ var SimulatorTransport = class {
|
|
|
3110
3429
|
};
|
|
3111
3430
|
//#endregion
|
|
3112
3431
|
exports.B2Simulator = B2Simulator;
|
|
3432
|
+
exports.BUCKET_INFO_KEY_MAX_BYTES = require_bucket.BUCKET_INFO_KEY_MAX_BYTES;
|
|
3433
|
+
exports.BUCKET_INFO_KEY_MIN_BYTES = require_bucket.BUCKET_INFO_KEY_MIN_BYTES;
|
|
3434
|
+
exports.BUCKET_INFO_KEY_PATTERN = require_bucket.BUCKET_INFO_KEY_PATTERN;
|
|
3113
3435
|
exports.BUCKET_INFO_MAX_KEYS = require_validation.BUCKET_INFO_MAX_KEYS;
|
|
3436
|
+
exports.BUCKET_INFO_RESERVED_PREFIX = require_bucket.BUCKET_INFO_RESERVED_PREFIX;
|
|
3437
|
+
exports.BUCKET_INFO_VALUES_MAX_BYTES = require_bucket.BUCKET_INFO_VALUES_MAX_BYTES;
|
|
3114
3438
|
exports.BUCKET_INFO_VALUE_MAX = require_validation.BUCKET_INFO_VALUE_MAX;
|
|
3115
3439
|
exports.BUCKET_NAME_MAX = require_b2_naming.BUCKET_NAME_MAX;
|
|
3116
3440
|
exports.BUCKET_NAME_MIN = require_b2_naming.BUCKET_NAME_MIN;
|
|
3441
|
+
exports.CORS_MAX_AGE_SECONDS_MAX = require_bucket.CORS_MAX_AGE_SECONDS_MAX;
|
|
3442
|
+
exports.CORS_RULES_MAX_COUNT = require_bucket.CORS_RULES_MAX_COUNT;
|
|
3443
|
+
exports.CORS_RULE_MAX_BYTES = require_bucket.CORS_RULE_MAX_BYTES;
|
|
3444
|
+
exports.CORS_RULE_NAME_MAX_LENGTH = require_bucket.CORS_RULE_NAME_MAX_LENGTH;
|
|
3445
|
+
exports.CORS_RULE_NAME_MIN_LENGTH = require_bucket.CORS_RULE_NAME_MIN_LENGTH;
|
|
3446
|
+
exports.CORS_RULE_NAME_PATTERN = require_bucket.CORS_RULE_NAME_PATTERN;
|
|
3447
|
+
exports.CORS_RULE_NAME_RESERVED_PREFIX = require_bucket.CORS_RULE_NAME_RESERVED_PREFIX;
|
|
3117
3448
|
exports.DOWNLOAD_AUTH_DURATION_MAX_SECONDS = require_validation.DOWNLOAD_AUTH_DURATION_MAX_SECONDS;
|
|
3118
3449
|
exports.DOWNLOAD_AUTH_DURATION_MIN_SECONDS = require_validation.DOWNLOAD_AUTH_DURATION_MIN_SECONDS;
|
|
3119
3450
|
exports.FILE_INFO_TOTAL_MAX = require_validation.FILE_INFO_TOTAL_MAX;
|