@voltro/plugin-storage 0.86.0 → 0.87.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/dist/access.js CHANGED
@@ -1,33 +1,33 @@
1
- import { randomBytes as e, scryptSync as t, timingSafeEqual as n } from "node:crypto";
2
- import { Effect as r } from "effect";
1
+ import { Effect as e } from "effect";
2
+ import { randomBytes as t, scryptSync as n, timingSafeEqual as r } from "node:crypto";
3
3
  //#region src/access.ts
4
- var i = (n) => {
5
- let r = e(16).toString("hex");
6
- return `${r}:${t(n, r, 32).toString("hex")}`;
7
- }, a = (e, r) => {
8
- if (!e || !r) return !1;
9
- let [i, a] = r.split(":");
4
+ var i = (e) => {
5
+ let r = t(16).toString("hex");
6
+ return `${r}:${n(e, r, 32).toString("hex")}`;
7
+ }, a = (e, t) => {
8
+ if (!e || !t) return !1;
9
+ let [i, a] = t.split(":");
10
10
  if (!i || !a) return !1;
11
- let o = Buffer.from(a, "hex"), s = t(e, i, o.length);
12
- return s.length === o.length && n(s, o);
13
- }, o = (e) => Array.isArray(e) ? e.filter((e) => typeof e == "string") : [], s = (e) => o(e.metadata?.roles), c = (e) => o(e.scopes), l = (e, t) => e.some((e) => t.includes(e)), u = (e) => o(e.metadata?.groups), d = (e) => typeof e == "boolean" ? r.succeed(e) : r.isEffect(e) ? e : r.promise(() => e), f = (e, t, n = {}) => r.gen(function* () {
14
- if (t.id && e.ownerId && t.id === e.ownerId) return !0;
15
- let i = e.accessPolicy ?? [];
11
+ let o = Buffer.from(a, "hex"), s = n(e, i, o.length);
12
+ return s.length === o.length && r(s, o);
13
+ }, o = (e) => Array.isArray(e) ? e.filter((e) => typeof e == "string") : [], s = (e) => o(e.metadata?.roles), c = (e) => o(e.scopes), l = (e, t) => e.some((e) => t.includes(e)), u = (e) => o(e.metadata?.groups), d = (t) => typeof t == "boolean" ? e.succeed(t) : e.isEffect(t) ? t : e.promise(() => t), f = (t, n, r = {}) => e.gen(function* () {
14
+ if (n.id && t.ownerId && n.id === t.ownerId) return !0;
15
+ let i = t.accessPolicy ?? [];
16
16
  if (i.length === 0) return !1;
17
- let a = n.resolveGroups ? yield* r.promise(async () => await n.resolveGroups(t)) : u(t);
18
- for (let r of i) if (yield* p(r, e, t, a, n)) return !0;
17
+ let a = r.resolveGroups ? yield* e.promise(async () => await r.resolveGroups(n)) : u(n);
18
+ for (let e of i) if (yield* p(e, t, n, a, r)) return !0;
19
19
  return !1;
20
- }), p = (e, t, n, i, o) => r.gen(function* () {
21
- let r = !1, u = (e) => (r = !0, e);
22
- if (e.owner !== void 0 && e.owner && !u(!!n.id && !!t.ownerId && n.id === t.ownerId) || e.tenant !== void 0 && e.tenant && !u(!!n.tenantId && n.tenantId === t.tenantId) || e.apiKey !== void 0 && e.apiKey && !u(n.type === "apiKey") || e.roles && e.roles.length > 0 && !u(l(s(n), e.roles)) || e.groups && e.groups.length > 0 && !u(l(i, e.groups)) || e.scopes && e.scopes.length > 0 && !u(l(c(n), e.scopes)) || e.password !== void 0 && e.password && !u(a(o.password, t.passwordHash))) return !1;
23
- if (e.guard) {
24
- let r = o.guards?.[e.guard];
25
- if (!u(r ? yield* d(r({
26
- subject: n,
27
- ref: t
20
+ }), p = (t, n, r, i, o) => e.gen(function* () {
21
+ let e = !1, u = (t) => (e = !0, t);
22
+ if (t.owner !== void 0 && t.owner && !u(!!r.id && !!n.ownerId && r.id === n.ownerId) || t.tenant !== void 0 && t.tenant && !u(!!r.tenantId && r.tenantId === n.tenantId) || t.apiKey !== void 0 && t.apiKey && !u(r.type === "apiKey") || t.roles && t.roles.length > 0 && !u(l(s(r), t.roles)) || t.groups && t.groups.length > 0 && !u(l(i, t.groups)) || t.scopes && t.scopes.length > 0 && !u(l(c(r), t.scopes)) || t.password !== void 0 && t.password && !u(a(o.password, n.passwordHash))) return !1;
23
+ if (t.guard) {
24
+ let e = o.guards?.[t.guard];
25
+ if (!u(e ? yield* d(e({
26
+ subject: r,
27
+ ref: n
28
28
  })) : !1)) return !1;
29
29
  }
30
- return r;
30
+ return e;
31
31
  }), m = (e, t) => {
32
32
  let n = [];
33
33
  e.id && n.push({
@@ -42,6 +42,6 @@ var i = (n) => {
42
42
  }, h = (e, t, n, r, i) => {
43
43
  let a = m(t, n);
44
44
  return e.some((e) => e.expiresAt && e.expiresAt.getTime() < i || r === "write" && e.permission !== "write" ? !1 : a.some((t) => t.type === e.principalType && t.id === e.principalId));
45
- }, g = (e, t) => t.resolveGroups ? r.promise(async () => await t.resolveGroups(e)) : r.succeed(u(e));
45
+ }, g = (t, n) => n.resolveGroups ? e.promise(async () => await n.resolveGroups(t)) : e.succeed(u(t));
46
46
  //#endregion
47
47
  export { f as evaluatePolicy, h as grantsAllow, i as hashPassword, g as resolveSubjectGroups, m as subjectPrincipals, a as verifyPassword };
@@ -0,0 +1,3 @@
1
+ export declare const storageByteSecurityHeaders: (contentType: string) => Readonly<Record<string, string>>;
2
+
3
+ export { }
@@ -0,0 +1,7 @@
1
+ //#region src/byteSecurity.ts
2
+ var e = /^(?:image\/(?!svg)|video\/|audio\/|application\/pdf(?:;|$)|text\/plain(?:;|$))/i, t = (t) => ({
3
+ "x-content-type-options": "nosniff",
4
+ "content-disposition": e.test(t) ? "inline" : "attachment"
5
+ });
6
+ //#endregion
7
+ export { t as storageByteSecurityHeaders };
@@ -0,0 +1,99 @@
1
+ import { storageObjectNamespace as e } from "./storageNamespaces.js";
2
+ import { azureConnectionTransport as t, databaseProvider as n, filesystemProvider as r, memoryProviderWithState as i, s3ConnectionTransport as a } from "./providers.js";
3
+ import { StorageError as o } from "@voltro/kv/storage";
4
+ import { Effect as s } from "effect";
5
+ //#region src/connection.ts
6
+ var c = (t, n = "") => {
7
+ if (!n) return t;
8
+ let r = (e) => `${n}${e}`;
9
+ return {
10
+ ...t,
11
+ objectNamespace: t.objectNamespace.pipe(s.map((t) => e([
12
+ "prefixed-object-namespace",
13
+ t,
14
+ n
15
+ ]))),
16
+ ...t.objectLocation === void 0 ? {} : { objectLocation: (e) => t.objectLocation(r(e)) },
17
+ put: (e, ...n) => t.put(r(e), ...n),
18
+ get: (e) => t.get(r(e)),
19
+ delete: (e) => t.delete(r(e)),
20
+ head: (e) => t.head(r(e)),
21
+ getUrl: (e, ...n) => t.getUrl(r(e), ...n),
22
+ ...t.publicUrl === void 0 ? {} : { publicUrl: (e) => t.publicUrl(r(e)) },
23
+ ...t.setObjectPublic === void 0 ? {} : { setObjectPublic: (e, n) => t.setObjectPublic(r(e), n) },
24
+ ...t.getUploadUrl === void 0 ? {} : { getUploadUrl: (e, n, i) => t.getUploadUrl(r(e), n, i) },
25
+ ...t.createMultipartUpload === void 0 ? {} : { createMultipartUpload: (e, n, i) => t.createMultipartUpload(r(e), n, i) },
26
+ ...t.presignUploadPart === void 0 ? {} : { presignUploadPart: (e, n, i, a) => t.presignUploadPart(r(e), n, i, a) },
27
+ ...t.completeMultipartUpload === void 0 ? {} : { completeMultipartUpload: (e, n, i) => t.completeMultipartUpload(r(e), n, i) },
28
+ ...t.abortMultipartUpload === void 0 ? {} : { abortMultipartUpload: (e, n) => t.abortMultipartUpload(r(e), n) },
29
+ ...t.getStream === void 0 ? {} : { getStream: (e) => t.getStream(r(e)) },
30
+ ...t.putStream === void 0 ? {} : { putStream: (e, n, i) => t.putStream(r(e), n, i) },
31
+ ...t.getRange === void 0 ? {} : { getRange: (e, n, i) => t.getRange(r(e), n, i) }
32
+ };
33
+ }, l = (e, l) => s.suspend(() => {
34
+ let u;
35
+ switch (e.provider) {
36
+ case "s3":
37
+ case "minio":
38
+ u = a({
39
+ bucket: e.bucket,
40
+ name: e.provider,
41
+ ...e.region === void 0 ? {} : { region: e.region },
42
+ ...e.endpoint === void 0 ? {} : { endpoint: e.endpoint },
43
+ ...e.accessKeyId === void 0 ? {} : { accessKeyId: e.accessKeyId },
44
+ ...e.secretAccessKey === void 0 ? {} : { secretAccessKey: e.secretAccessKey },
45
+ ...e.cdnBaseUrl === void 0 ? {} : { cdnBaseUrl: e.cdnBaseUrl },
46
+ ...e.publicAcl === void 0 ? {} : { publicAcl: e.publicAcl },
47
+ forcePathStyle: e.forcePathStyle ?? e.provider === "minio"
48
+ });
49
+ break;
50
+ case "filesystem":
51
+ u = {
52
+ provider: r({ root: e.root }),
53
+ close: s.void,
54
+ probe: s.tryPromise({
55
+ try: async () => {
56
+ let t = await import("node:fs/promises");
57
+ if (!(await t.stat(e.root)).isDirectory()) throw Error("Storage root must be a directory");
58
+ await t.access(e.root);
59
+ },
60
+ catch: () => new o({
61
+ provider: "filesystem",
62
+ message: "Storage root is not readable",
63
+ transient: !1
64
+ })
65
+ })
66
+ };
67
+ break;
68
+ case "memory":
69
+ u = {
70
+ provider: i(l.memory ?? /* @__PURE__ */ new Map()),
71
+ probe: s.void,
72
+ close: s.void
73
+ };
74
+ break;
75
+ case "database": {
76
+ let e = n();
77
+ u = {
78
+ provider: e,
79
+ probe: e.head("_connection_readiness").pipe(s.asVoid),
80
+ close: s.void
81
+ };
82
+ break;
83
+ }
84
+ case "azure": u = t({
85
+ container: e.bucket,
86
+ ...e.accountName === void 0 ? {} : { accountName: e.accountName },
87
+ ...e.accountKey === void 0 ? {} : { accountKey: e.accountKey },
88
+ ...e.connectionString === void 0 ? {} : { connectionString: e.connectionString },
89
+ ...e.endpoint === void 0 ? {} : { endpoint: e.endpoint },
90
+ ...e.cdnBaseUrl === void 0 ? {} : { cdnBaseUrl: e.cdnBaseUrl }
91
+ });
92
+ }
93
+ return s.succeed({
94
+ ...u,
95
+ provider: c(u.provider, e.keyPrefix)
96
+ });
97
+ });
98
+ //#endregion
99
+ export { l as connectStorage, c as withStorageKeyPrefix };
@@ -0,0 +1,132 @@
1
+ import { StorageError as e } from "./types.js";
2
+ import { storageMetadataError as t } from "./metadataError.js";
3
+ import { readRetainedStorageObject as n } from "./retainedObjects.js";
4
+ import { abandonRetainedCapture as r, admitRetainedCaptureObject as i, inspectRetainedSource as a, registerRetainedCapture as o, retainedCaptureItems as s, runRetainedCapture as c, sealRetainedCapture as l } from "./retainedCapture.js";
5
+ import { Context as u, Effect as d, Layer as f, Schema as p, Stream as m } from "effect";
6
+ import { canonicalJson as h, pluginInstanceName as g } from "@voltro/protocol";
7
+ //#region src/custody.ts
8
+ var _ = "@voltro/plugin-storage", v = (e) => g({
9
+ base: _,
10
+ alias: e.alias,
11
+ instance: e.name
12
+ }), y = (e) => `${_}/StorageCustody:${JSON.stringify(e)}`, b = class extends u.Service()(y(_)) {
13
+ static withSource(e) {
14
+ return d.suspend(() => {
15
+ let t = E.get(e.source), n = E.get(e.destination);
16
+ return t === void 0 || n === void 0 ? d.fail(x("Custody transfer requires configured storage services")) : t !== n && v(t.selection) === v(n.selection) ? d.fail(x("Custody source and destination need distinct configured instance identities")) : d.succeed(D(n, t));
17
+ });
18
+ }
19
+ static forInstance(e = {}) {
20
+ return u.Service(y(v(e)));
21
+ }
22
+ }, x = (t, n = 409) => new e({
23
+ provider: "custody",
24
+ message: t,
25
+ status: n,
26
+ transient: !1
27
+ }), S = (n) => p.is(e)(n) ? n : t(n, "custody"), C = (e) => d.tryPromise({
28
+ try: e,
29
+ catch: S
30
+ }), w = (e) => ({
31
+ id: e.id,
32
+ instance: e.instance,
33
+ objectNamespace: e.objectNamespace,
34
+ tenantId: e.tenantId,
35
+ bucket: e.bucket,
36
+ contextDigest: e.contextDigest,
37
+ ...e.source === void 0 ? {} : { source: {
38
+ instance: e.source.instance,
39
+ objectNamespace: e.source.objectNamespace,
40
+ bucket: e.source.bucket
41
+ } }
42
+ }), T = (e) => ({
43
+ ...w(e),
44
+ count: e.count,
45
+ digest: e.digest
46
+ }), E = /* @__PURE__ */ new WeakMap(), D = (e, t = e) => {
47
+ let u = v(t.selection), f = v(e.selection), p = e.bucket, g = e.provider, _ = (t) => d.gen(function* () {
48
+ let n = yield* g.objectNamespace;
49
+ if (t !== void 0 && (t.instance !== f || t.bucket !== p || t.objectNamespace !== n)) return yield* d.fail(x("Capture belongs to another storage instance or bucket", 403));
50
+ let r = e.store();
51
+ return yield* r === void 0 ? d.fail(x("Storage custody requires a bound database and the default reference and grant stores")) : d.succeed(r);
52
+ }), y = () => d.gen(function* () {
53
+ let e = yield* t.provider.objectNamespace;
54
+ return u === f && t.bucket === p ? void 0 : {
55
+ instance: u,
56
+ objectNamespace: e,
57
+ bucket: t.bucket
58
+ };
59
+ }), b = () => d.gen(function* () {
60
+ let e = yield* _();
61
+ return t.store() === e ? e : yield* d.fail(x("Custody source and destination must share the bound application database"));
62
+ }), D = {
63
+ inspect: (e, n) => d.gen(function* () {
64
+ let r = n.id, i = n.tenantId;
65
+ yield* b();
66
+ let o = yield* t.provider.objectNamespace;
67
+ return yield* C(() => a(e, {
68
+ instance: u,
69
+ objectNamespace: o,
70
+ bucket: t.bucket,
71
+ tenantId: i
72
+ }, r));
73
+ }),
74
+ register: (e, t) => d.gen(function* () {
75
+ let n = yield* y(), r = {
76
+ id: t.id,
77
+ instance: f,
78
+ objectNamespace: yield* g.objectNamespace,
79
+ tenantId: t.tenantId,
80
+ bucket: p,
81
+ contextDigest: t.contextDigest,
82
+ ...n === void 0 ? {} : { source: n }
83
+ }, i = t.maxBytes, a = t.sources;
84
+ return yield* b(), {
85
+ key: r,
86
+ count: (yield* C(() => o(e, r, {
87
+ maxBytes: i,
88
+ sources: a
89
+ }))).count
90
+ };
91
+ }),
92
+ run: (n) => d.gen(function* () {
93
+ let r = w(n);
94
+ yield* _(r);
95
+ let i = yield* b();
96
+ yield* c(i, g, r, e.quota, {
97
+ instance: u,
98
+ bucket: t.bucket,
99
+ provider: t.provider
100
+ }).pipe(d.mapError(S));
101
+ }),
102
+ seal: (e, t) => d.gen(function* () {
103
+ let n = w(t);
104
+ return yield* _(n), yield* C(() => l(e, n));
105
+ }),
106
+ items: (e, t) => m.unwrap(d.gen(function* () {
107
+ let n = T(e), r = yield* _(n);
108
+ return m.fromAsyncIterable(s(t ?? r, n), S);
109
+ })),
110
+ read: (e, t, r) => d.gen(function* () {
111
+ let a = T(e), o = yield* d.try({
112
+ try: () => JSON.parse(h(t)),
113
+ catch: S
114
+ }), s = {
115
+ storageInstance: f,
116
+ tenantId: r.tenantId,
117
+ maxBytes: r.maxBytes,
118
+ bucket: p
119
+ };
120
+ if (a.tenantId !== s.tenantId || o.tenantId !== s.tenantId) return yield* d.fail(x("Capture tenant does not match admitted tenant", 403));
121
+ let c = yield* _(a);
122
+ return yield* C(() => i(c, a, o)), yield* n(c, g, o, s).pipe(d.mapError(S));
123
+ }),
124
+ abandon: (e) => d.gen(function* () {
125
+ let t = w(e), n = yield* _(t);
126
+ yield* r(n, g, t).pipe(d.mapError(S));
127
+ })
128
+ };
129
+ return E.set(D, e), D;
130
+ }, O = (e) => f.succeed(b.forInstance(e.selection), D(e));
131
+ //#endregion
132
+ export { b as StorageCustody, O as storageCustodyLayer };
package/dist/env.js CHANGED
@@ -131,7 +131,13 @@ var t = e([
131
131
  name: "VOLTRO_STORAGE_SECRET",
132
132
  required: !1,
133
133
  secret: !0,
134
- description: "HMAC secret for signed grant tokens. Falls back to the session secret."
134
+ description: "HMAC secret for signed storage links and upload tickets. Falls back to the session secret (and its VOLTRO_SESSION_SECRET_PREVIOUS)."
135
+ },
136
+ {
137
+ name: "VOLTRO_STORAGE_SECRET_PREVIOUS",
138
+ required: !1,
139
+ secret: !0,
140
+ description: "During a VOLTRO_STORAGE_SECRET rotation: the secret links and tickets were signed with until now. They keep verifying until they expire; then remove it."
135
141
  },
136
142
  {
137
143
  name: "VOLTRO_SESSION_COOKIE",
package/dist/grant.js CHANGED
@@ -1,112 +1,132 @@
1
1
  import { storageEnv as e } from "./env.js";
2
- import { createHmac as t, timingSafeEqual as n } from "node:crypto";
3
- import { Exit as r, Schema as i } from "effect";
2
+ import { Exit as t, Schema as n } from "effect";
3
+ import { createHmac as r, timingSafeEqual as i } from "node:crypto";
4
4
  import { StorageAccessPolicySchema as a } from "@voltro/protocol";
5
- import { resolveSessionSecret as o } from "@voltro/protocol/session";
5
+ import { noteConfigured as o, noteSigned as s, noteSigningLifetime as c, previousAccepted as l, resolveSessionSecrets as u } from "@voltro/protocol/session";
6
6
  //#region src/grant.ts
7
- var s = () => e.read("VOLTRO_STORAGE_SECRET") ?? o(), c = (e) => (typeof e == "string" ? Buffer.from(e, "utf8") : e).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, ""), l = (e) => {
7
+ var d = () => {
8
+ let t = e.read("VOLTRO_STORAGE_SECRET");
9
+ if (t !== void 0 && t !== "") {
10
+ let n = e.read("VOLTRO_STORAGE_SECRET_PREVIOUS");
11
+ return o("storage", t, n), n === void 0 || n === "" || n === t || !l("storage", n) ? [t] : [t, n];
12
+ }
13
+ let n = u();
14
+ return n.previous === void 0 ? [n.current.secret] : [n.current.secret, n.previous.secret];
15
+ }, f = (t, n) => {
16
+ s(t === e.read("VOLTRO_STORAGE_SECRET") ? "storage" : "session", t, n * 1e3);
17
+ }, p = (t) => {
18
+ c(e.read("VOLTRO_STORAGE_SECRET") ? "storage" : "session", t * 1e3);
19
+ }, m = () => d()[0], h = (e, t, n) => {
20
+ let a = v(t), o = !1;
21
+ for (let t of typeof n == "string" ? [n] : n) {
22
+ if (!t) continue;
23
+ let n = r("sha256", t).update(e).digest();
24
+ a.length === n.length && i(a, n) && (o = !0);
25
+ }
26
+ return o;
27
+ }, g = (e) => typeof e == "string" ? e.length > 0 : e.some((e) => e.length > 0), _ = (e) => (typeof e == "string" ? Buffer.from(e, "utf8") : e).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, ""), v = (e) => {
8
28
  let t = e.replace(/-/g, "+").replace(/_/g, "/") + "=".repeat((4 - e.length % 4) % 4);
9
29
  return Buffer.from(t, "base64");
10
- }, u = (e, n, r = s(), i = "/_voltro/storage") => {
11
- if (!r) throw Error("signGrant: secret must be a non-empty string");
30
+ }, y = (e, t, n = m(), i = "/_voltro/storage") => {
31
+ if (!n) throw Error("signGrant: secret must be a non-empty string");
12
32
  let a = {
13
33
  refId: e,
14
34
  audience: i,
15
- exp: Math.floor(Date.now() / 1e3) + Math.floor(n)
16
- }, o = c(JSON.stringify(a));
17
- return `${o}.${c(t("sha256", r).update(o).digest())}`;
18
- }, d = (e, r = s()) => {
19
- if (!e || !r) return null;
20
- let i = e.indexOf(".");
21
- if (i <= 0 || i === e.length - 1) return null;
22
- let a = e.slice(0, i), o = e.slice(i + 1), c = t("sha256", r).update(a).digest(), u = l(o);
23
- if (u.length !== c.length || !n(u, c)) return null;
35
+ exp: Math.floor(Date.now() / 1e3) + Math.floor(t)
36
+ }, o = _(JSON.stringify(a)), s = _(r("sha256", n).update(o).digest());
37
+ return f(n, a.exp), `${o}.${s}`;
38
+ }, b = (e, t = d()) => {
39
+ if (!e || !g(t)) return null;
40
+ let n = e.indexOf(".");
41
+ if (n <= 0 || n === e.length - 1) return null;
42
+ let r = e.slice(0, n);
43
+ if (!h(r, e.slice(n + 1), t)) return null;
24
44
  try {
25
- let e = JSON.parse(l(a).toString("utf8"));
45
+ let e = JSON.parse(v(r).toString("utf8"));
26
46
  return typeof e.audience != "string" || !e.audience || typeof e.refId != "string" || typeof e.exp != "number" || e.exp <= Math.floor(Date.now() / 1e3) ? null : e;
27
47
  } catch {
28
48
  return null;
29
49
  }
30
- }, f = (e) => e.version !== 2 || typeof e.writeScope != "string" || !/^[a-f0-9]{64}$/.test(e.writeScope) || Object.hasOwn(e, "replicaId") || e.issuerReplicaId !== void 0 && (typeof e.issuerReplicaId != "string" || !e.issuerReplicaId.trim()) ? !1 : e.access === void 0 || e.vis === "private" && r.isSuccess(i.decodeUnknownExit(a, { onExcessProperty: "error" })(e.access)), p = (e, n, r = s()) => {
31
- if (!r) throw Error("signUploadTicket: secret must be a non-empty string");
50
+ }, x = (e) => e.version !== 2 || typeof e.writeScope != "string" || !/^[a-f0-9]{64}$/.test(e.writeScope) || Object.hasOwn(e, "replicaId") || e.issuerReplicaId !== void 0 && (typeof e.issuerReplicaId != "string" || !e.issuerReplicaId.trim()) ? !1 : e.access === void 0 || e.vis === "private" && t.isSuccess(n.decodeUnknownExit(a, { onExcessProperty: "error" })(e.access)), S = (e, t, n = m()) => {
51
+ if (!n) throw Error("signUploadTicket: secret must be a non-empty string");
32
52
  let i = {
33
53
  ...e,
34
54
  version: 2,
35
- exp: Math.floor(Date.now() / 1e3) + Math.floor(n)
36
- }, a = c(JSON.stringify(i));
37
- return `${a}.${c(t("sha256", r).update(`u:${a}`).digest())}`;
38
- }, m = (e, r = s()) => {
39
- if (!e || !r) return null;
40
- let i = e.indexOf(".");
41
- if (i <= 0 || i === e.length - 1) return null;
42
- let a = e.slice(0, i), o = e.slice(i + 1), c = t("sha256", r).update(`u:${a}`).digest(), u = l(o);
43
- if (u.length !== c.length || !n(u, c)) return null;
55
+ exp: Math.floor(Date.now() / 1e3) + Math.floor(t)
56
+ }, a = _(JSON.stringify(i)), o = _(r("sha256", n).update(`u:${a}`).digest());
57
+ return f(n, i.exp), `${a}.${o}`;
58
+ }, C = (e, t = d()) => {
59
+ if (!e || !g(t)) return null;
60
+ let n = e.indexOf(".");
61
+ if (n <= 0 || n === e.length - 1) return null;
62
+ let r = e.slice(0, n), i = e.slice(n + 1);
63
+ if (!h(`u:${r}`, i, t)) return null;
44
64
  try {
45
- let e = JSON.parse(l(a).toString("utf8"));
46
- return !f(e) || e.operationId !== void 0 && (typeof e.operationId != "string" || !e.operationId.trim() || e.operationId.length > 200) || typeof e.instance != "string" || !e.instance || typeof e.ct != "string" || typeof e.exp != "number" || e.vis !== "public" && e.vis !== "private" || e.exp <= Math.floor(Date.now() / 1e3) ? null : e;
65
+ let e = JSON.parse(v(r).toString("utf8"));
66
+ return !x(e) || e.operationId !== void 0 && (typeof e.operationId != "string" || !e.operationId.trim() || e.operationId.length > 200) || typeof e.instance != "string" || !e.instance || typeof e.ct != "string" || typeof e.exp != "number" || typeof e.destination != "string" || !e.destination || e.destination.includes("\0") || /[\uD800-\uDFFF]/u.test(e.destination) || e.vis !== "public" && e.vis !== "private" || e.exp <= Math.floor(Date.now() / 1e3) ? null : e;
47
67
  } catch {
48
68
  return null;
49
69
  }
50
- }, h = (e, n, r = s()) => {
51
- if (!r) throw Error("signFinalizeTicket: secret must be a non-empty string");
70
+ }, w = (e, t, n = m()) => {
71
+ if (!n) throw Error("signFinalizeTicket: secret must be a non-empty string");
52
72
  let i = {
53
73
  ...e,
54
74
  version: 2,
55
- exp: Math.floor(Date.now() / 1e3) + Math.floor(n)
56
- }, a = c(JSON.stringify(i));
57
- return `${a}.${c(t("sha256", r).update(`f:${a}`).digest())}`;
58
- }, g = (e, r = s()) => {
59
- if (!e || !r) return null;
60
- let i = e.indexOf(".");
61
- if (i <= 0 || i === e.length - 1) return null;
62
- let a = e.slice(0, i), o = e.slice(i + 1), c = t("sha256", r).update(`f:${a}`).digest(), u = l(o);
63
- if (u.length !== c.length || !n(u, c)) return null;
75
+ exp: Math.floor(Date.now() / 1e3) + Math.floor(t)
76
+ }, a = _(JSON.stringify(i)), o = _(r("sha256", n).update(`f:${a}`).digest());
77
+ return f(n, i.exp), `${a}.${o}`;
78
+ }, T = (e, t = d()) => {
79
+ if (!e || !g(t)) return null;
80
+ let n = e.indexOf(".");
81
+ if (n <= 0 || n === e.length - 1) return null;
82
+ let r = e.slice(0, n), i = e.slice(n + 1);
83
+ if (!h(`f:${r}`, i, t)) return null;
64
84
  try {
65
- let e = JSON.parse(l(a).toString("utf8"));
66
- return !f(e) || typeof e.key != "string" || e.key.length === 0 || typeof e.instance != "string" || !e.instance || typeof e.ct != "string" || typeof e.exp != "number" || e.vis !== "public" && e.vis !== "private" || e.exp <= Math.floor(Date.now() / 1e3) ? null : e;
85
+ let e = JSON.parse(v(r).toString("utf8"));
86
+ return !x(e) || typeof e.key != "string" || e.key.length === 0 || typeof e.instance != "string" || !e.instance || typeof e.ct != "string" || typeof e.exp != "number" || typeof e.destination != "string" || !e.destination || e.destination.includes("\0") || /[\uD800-\uDFFF]/u.test(e.destination) || e.vis !== "public" && e.vis !== "private" || e.exp <= Math.floor(Date.now() / 1e3) ? null : e;
67
87
  } catch {
68
88
  return null;
69
89
  }
70
- }, _ = (e, n, r = s()) => {
71
- if (!r) throw Error("signResumableTicket: secret must be a non-empty string");
90
+ }, E = (e, t, n = m()) => {
91
+ if (!n) throw Error("signResumableTicket: secret must be a non-empty string");
72
92
  let i = {
73
93
  ...e,
74
94
  version: 2,
75
- exp: Math.floor(Date.now() / 1e3) + Math.floor(n)
76
- }, a = c(JSON.stringify(i));
77
- return `${a}.${c(t("sha256", r).update(`r:${a}`).digest())}`;
78
- }, v = (e, r = s()) => {
79
- if (!e || !r) return null;
80
- let i = e.indexOf(".");
81
- if (i <= 0 || i === e.length - 1) return null;
82
- let a = e.slice(0, i), o = e.slice(i + 1), c = t("sha256", r).update(`r:${a}`).digest(), u = l(o);
83
- if (u.length !== c.length || !n(u, c)) return null;
95
+ exp: Math.floor(Date.now() / 1e3) + Math.floor(t)
96
+ }, a = _(JSON.stringify(i)), o = _(r("sha256", n).update(`r:${a}`).digest());
97
+ return f(n, i.exp), `${a}.${o}`;
98
+ }, D = (e, t = d()) => {
99
+ if (!e || !g(t)) return null;
100
+ let n = e.indexOf(".");
101
+ if (n <= 0 || n === e.length - 1) return null;
102
+ let r = e.slice(0, n), i = e.slice(n + 1);
103
+ if (!h(`r:${r}`, i, t)) return null;
84
104
  try {
85
- let e = JSON.parse(l(a).toString("utf8"));
86
- return !f(e) || typeof e.id != "string" || e.id.length === 0 || typeof e.size != "number" || e.size < 0 || typeof e.instance != "string" || !e.instance || typeof e.ct != "string" || typeof e.exp != "number" || e.vis !== "public" && e.vis !== "private" || e.exp <= Math.floor(Date.now() / 1e3) ? null : e;
105
+ let e = JSON.parse(v(r).toString("utf8"));
106
+ return !x(e) || typeof e.id != "string" || e.id.length === 0 || typeof e.size != "number" || e.size < 0 || typeof e.instance != "string" || !e.instance || typeof e.ct != "string" || typeof e.exp != "number" || typeof e.destination != "string" || !e.destination || e.destination.includes("\0") || /[\uD800-\uDFFF]/u.test(e.destination) || e.vis !== "public" && e.vis !== "private" || e.exp <= Math.floor(Date.now() / 1e3) ? null : e;
87
107
  } catch {
88
108
  return null;
89
109
  }
90
- }, y = (e, n, r = s()) => {
91
- if (!r) throw Error("signMultipartTicket: secret must be a non-empty string");
110
+ }, O = (e, t, n = m()) => {
111
+ if (!n) throw Error("signMultipartTicket: secret must be a non-empty string");
92
112
  let i = {
93
113
  ...e,
94
114
  version: 2,
95
- exp: Math.floor(Date.now() / 1e3) + Math.floor(n)
96
- }, a = c(JSON.stringify(i));
97
- return `${a}.${c(t("sha256", r).update(`m:${a}`).digest())}`;
98
- }, b = (e, r = s()) => {
99
- if (!e || !r) return null;
100
- let i = e.indexOf(".");
101
- if (i <= 0 || i === e.length - 1) return null;
102
- let a = e.slice(0, i), o = e.slice(i + 1), c = t("sha256", r).update(`m:${a}`).digest(), u = l(o);
103
- if (u.length !== c.length || !n(u, c)) return null;
115
+ exp: Math.floor(Date.now() / 1e3) + Math.floor(t)
116
+ }, a = _(JSON.stringify(i)), o = _(r("sha256", n).update(`m:${a}`).digest());
117
+ return f(n, i.exp), `${a}.${o}`;
118
+ }, k = (e, t = d()) => {
119
+ if (!e || !g(t)) return null;
120
+ let n = e.indexOf(".");
121
+ if (n <= 0 || n === e.length - 1) return null;
122
+ let r = e.slice(0, n), i = e.slice(n + 1);
123
+ if (!h(`m:${r}`, i, t)) return null;
104
124
  try {
105
- let e = JSON.parse(l(a).toString("utf8"));
106
- return !f(e) || typeof e.key != "string" || e.key.length === 0 || typeof e.uploadId != "string" || e.uploadId.length === 0 || typeof e.instance != "string" || !e.instance || typeof e.ct != "string" || typeof e.exp != "number" || e.vis !== "public" && e.vis !== "private" || e.exp <= Math.floor(Date.now() / 1e3) ? null : e;
125
+ let e = JSON.parse(v(r).toString("utf8"));
126
+ return !x(e) || typeof e.key != "string" || e.key.length === 0 || typeof e.uploadId != "string" || e.uploadId.length === 0 || typeof e.instance != "string" || !e.instance || typeof e.ct != "string" || typeof e.exp != "number" || typeof e.destination != "string" || !e.destination || e.destination.includes("\0") || /[\uD800-\uDFFF]/u.test(e.destination) || e.vis !== "public" && e.vis !== "private" || e.exp <= Math.floor(Date.now() / 1e3) ? null : e;
107
127
  } catch {
108
128
  return null;
109
129
  }
110
130
  };
111
131
  //#endregion
112
- export { s as resolveStorageSecret, h as signFinalizeTicket, u as signGrant, y as signMultipartTicket, _ as signResumableTicket, p as signUploadTicket, g as verifyFinalizeTicket, d as verifyGrant, b as verifyMultipartTicket, v as verifyResumableTicket, m as verifyUploadTicket };
132
+ export { p as declareStorageSigningLifetime, m as resolveStorageSecret, d as resolveStorageSecrets, w as signFinalizeTicket, y as signGrant, O as signMultipartTicket, E as signResumableTicket, S as signUploadTicket, T as verifyFinalizeTicket, b as verifyGrant, k as verifyMultipartTicket, D as verifyResumableTicket, C as verifyUploadTicket };