@voltro/plugin-licensing 0.86.0 → 0.88.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/snapshot.js CHANGED
@@ -1,21 +1,32 @@
1
- //#region src/snapshot.ts
1
+ // src/snapshot.ts
2
2
  var e = (e, t = {}) => {
3
- let n = new Set(e.features), r = new Set(e.plugins), i = t.graceSeconds ?? 0, a = t.now ?? (() => Date.now() / 1e3), o = () => e.exp <= 0 || a() <= e.exp + i;
4
- return {
5
- claims: e,
6
- state: () => e.exp <= 0 || a() <= e.exp ? "active" : o() ? "grace" : "expired",
7
- limitFor: (t, n) => {
8
- if (!o() || e.tenant !== void 0 && e.tenant !== t) return;
9
- let r = e.entitlements[n];
10
- if (r !== void 0) return r === "unlimited" ? Infinity : r;
3
+ let n = {};
4
+ for (let [t, r] of Object.entries(e.entitlements)) Object.defineProperty(n, t, {
5
+ value: r,
6
+ enumerable: !0
7
+ });
8
+ let r = Object.freeze({
9
+ ...e,
10
+ entitlements: Object.freeze(n),
11
+ features: Object.freeze([...e.features]),
12
+ plugins: Object.freeze([...e.plugins])
13
+ }), i = new Set(r.features), a = new Set(r.plugins), o = t.graceSeconds ?? 0;
14
+ if (!Number.isSafeInteger(o) || o < 0) throw TypeError("Invalid license snapshot grace");
15
+ let s = t.now ?? (() => Date.now() / 1e3), c = () => r.exp <= 0 || s() < r.exp + o;
16
+ return Object.freeze({
17
+ claims: r,
18
+ state: () => r.exp <= 0 || s() < r.exp ? "active" : c() ? "grace" : "expired",
19
+ limitFor: (e, t) => {
20
+ if (!c() || r.tenant !== void 0 && r.tenant !== e || !Object.hasOwn(r.entitlements, t)) return;
21
+ let n = r.entitlements[t];
22
+ if (n !== void 0) return n === "unlimited" ? Infinity : n;
11
23
  },
12
- hasFeature: (e) => o() && n.has(e),
13
- allowsPlugin: (e) => o() && r.has(e)
14
- };
24
+ hasFeature: (e) => c() && i.has(e),
25
+ allowsPlugin: (e) => c() && a.has(e)
26
+ });
15
27
  }, t, n = (e) => {
16
28
  t = e;
17
29
  }, r = () => t, i, a = (e) => {
18
30
  i = e;
19
31
  }, o = () => i;
20
- //#endregion
21
32
  export { o as getRejection, r as getSnapshot, e as makeSnapshot, a as setRejection, n as setSnapshot };
package/dist/verify.js CHANGED
@@ -1,55 +1,87 @@
1
1
  import { Data as e, Effect as t } from "effect";
2
- import { importSPKI as n, jwtVerify as r } from "jose";
3
- //#region src/verify.ts
4
- var i = class extends e.TaggedError("LicenseVerifyError") {}, a = (e) => typeof e == "object" && e && "code" in e ? String(e.code) : "", o = (e) => {
2
+ import { decodeProtectedHeader as n, errors as r, importSPKI as i, jwtVerify as a } from "jose";
3
+ // src/verify.ts
4
+ var o = class extends e.TaggedError("LicenseVerifyError") {}, s = (e) => typeof e == "object" && e && "code" in e ? String(e.code) : "", c = (e) => {
5
5
  let t = e instanceof Error ? e.message : String(e);
6
- return a(e) === "ERR_JWT_EXPIRED" ? new i({
6
+ return s(e) === "ERR_JWT_EXPIRED" ? new o({
7
7
  reason: "expired",
8
8
  message: t
9
- }) : new i({
9
+ }) : new o({
10
10
  reason: "invalid",
11
11
  message: t
12
12
  });
13
- }, s = (e) => e === "unlimited" || typeof e == "number" && Number.isFinite(e) && e >= 0, c = (e, n) => {
14
- let r = e.edition, a = e.entitlements, o = e.features;
15
- if (typeof r != "string" || typeof a != "object" || !a) return t.fail(new i({
13
+ }, l = (e) => e === "unlimited" || typeof e == "number" && Number.isFinite(e) && e >= 0, u = (e) => typeof e == "string" && e.length > 0 && e.length <= 256 && e.trim() === e, d = (e) => Array.isArray(e) && e.every(u), f = (e) => typeof e == "number" && Number.isSafeInteger(e) && e >= 0 && e <= 864e10, p = (e, n) => {
14
+ let r = e.edition, i = e.entitlements, a = e.features, s = e.plugins, c = e.tenant;
15
+ if (!u(r) || typeof i != "object" || !i || Array.isArray(i)) return t.fail(new o({
16
16
  reason: "malformed",
17
17
  message: "missing edition/entitlements"
18
18
  }));
19
- let c = {};
20
- for (let [e, n] of Object.entries(a)) {
21
- if (!s(n)) return t.fail(new i({
19
+ if (c !== void 0 && !u(c) || a !== void 0 && !d(a) || s !== void 0 && !d(s)) return t.fail(new o({
20
+ reason: "malformed",
21
+ message: "invalid license scope or grants"
22
+ }));
23
+ if (e.exp !== void 0 && !f(e.exp) || e.iat !== void 0 && !f(e.iat) || n !== void 0 && !u(n)) return t.fail(new o({
24
+ reason: "malformed",
25
+ message: "invalid license time or key identity"
26
+ }));
27
+ let p = {};
28
+ for (let [e, n] of Object.entries(i)) {
29
+ if (!u(e) || !l(n)) return t.fail(new o({
22
30
  reason: "malformed",
23
31
  message: `bad entitlement '${e}'`
24
32
  }));
25
- c[e] = n;
33
+ Object.defineProperty(p, e, {
34
+ value: n,
35
+ enumerable: !0
36
+ });
26
37
  }
27
- let l = Array.isArray(o) ? o.filter((e) => typeof e == "string") : [], u = e.plugins, d = Array.isArray(u) ? u.filter((e) => typeof e == "string") : [];
38
+ let m = a === void 0 ? [] : a, h = s === void 0 ? [] : s;
28
39
  return t.succeed({
29
- ...typeof e.tenant == "string" ? { tenant: e.tenant } : {},
40
+ ...c === void 0 ? {} : { tenant: c },
30
41
  edition: r,
31
- entitlements: c,
32
- features: l,
33
- plugins: d,
42
+ entitlements: p,
43
+ features: m,
44
+ plugins: h,
34
45
  exp: typeof e.exp == "number" ? e.exp : 0,
35
46
  ...typeof e.iat == "number" ? { iat: e.iat } : {},
36
47
  ...n === void 0 ? {} : { kid: n }
37
48
  });
38
- }, l = (e, a) => t.tryPromise({
39
- try: () => n(a, "EdDSA"),
40
- catch: (e) => new i({
41
- reason: "key",
42
- message: e instanceof Error ? e.message : String(e)
43
- })
44
- }).pipe(t.flatMap((n) => t.tryPromise({
45
- try: async () => {
46
- let { payload: t, protectedHeader: i } = await r(e, n, { algorithms: ["EdDSA"] });
47
- return {
48
- payload: t,
49
- kid: i.kid
50
- };
51
- },
52
- catch: o
53
- })), t.flatMap(({ payload: e, kid: t }) => c(e, t)));
54
- //#endregion
55
- export { i as LicenseVerifyError, l as verifyLicense };
49
+ }, m = (e, s, l = {}) => {
50
+ let u = l.graceSeconds ?? 0, d = l.nowSeconds;
51
+ return t.suspend(() => {
52
+ let l = d ?? Math.floor(Date.now() / 1e3);
53
+ return !Number.isSafeInteger(u) || u < 0 || !Number.isSafeInteger(l) || l < 0 || !Number.isFinite((/* @__PURE__ */ new Date(l * 1e3)).getTime()) ? t.fail(new o({
54
+ reason: "malformed",
55
+ message: "invalid trusted verification clock or grace"
56
+ })) : t.tryPromise({
57
+ try: () => i(s, "EdDSA"),
58
+ catch: (e) => new o({
59
+ reason: "key",
60
+ message: e instanceof Error ? e.message : String(e)
61
+ })
62
+ }).pipe(t.flatMap((i) => t.tryPromise({
63
+ try: async () => {
64
+ try {
65
+ let { payload: t, protectedHeader: n } = await a(e, i, {
66
+ algorithms: ["EdDSA"],
67
+ currentDate: /* @__PURE__ */ new Date(l * 1e3)
68
+ });
69
+ return {
70
+ payload: t,
71
+ kid: n.kid
72
+ };
73
+ } catch (t) {
74
+ if (!(t instanceof r.JWTExpired) || t.claim !== "exp" || u === 0) throw t;
75
+ let i = t.payload.exp;
76
+ if (i === void 0 || !Number.isSafeInteger(i) || i <= 0 || !Number.isSafeInteger(i + u) || l >= i + u) throw t;
77
+ return {
78
+ payload: t.payload,
79
+ kid: n(e).kid
80
+ };
81
+ }
82
+ },
83
+ catch: c
84
+ })), t.flatMap(({ payload: e, kid: t }) => p(e, t)));
85
+ });
86
+ };
87
+ export { o as LicenseVerifyError, m as verifyLicense };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voltro/plugin-licensing",
3
- "version": "0.86.0",
3
+ "version": "0.88.0",
4
4
  "description": "Offline-verified license keys + cloud-issued entitlement snapshots for @voltro apps",
5
5
  "keywords": [
6
6
  "voltro",
@@ -28,7 +28,27 @@
28
28
  "import": "./dist/sign.js",
29
29
  "default": "./dist/sign.js"
30
30
  },
31
- "./package.json": "./package.json"
31
+ "./package.json": "./package.json",
32
+ "./games": {
33
+ "types": "./dist/games.d.ts",
34
+ "import": "./dist/games.js",
35
+ "default": "./dist/games.js"
36
+ },
37
+ "./cloud": {
38
+ "types": "./dist/cloud.d.ts",
39
+ "import": "./dist/cloud.js",
40
+ "default": "./dist/cloud.js"
41
+ },
42
+ "./gate": {
43
+ "types": "./dist/gate.d.ts",
44
+ "import": "./dist/gate.js",
45
+ "default": "./dist/gate.js"
46
+ },
47
+ "./inspect": {
48
+ "types": "./dist/inspect.d.ts",
49
+ "import": "./dist/inspect.js",
50
+ "default": "./dist/inspect.js"
51
+ }
32
52
  },
33
53
  "main": "./dist/index.js",
34
54
  "module": "./dist/index.js",
@@ -38,14 +58,14 @@
38
58
  "node": ">=24.0.0"
39
59
  },
40
60
  "dependencies": {
41
- "@voltro/database": "0.86.0",
42
- "@voltro/env": "0.86.0",
43
- "@voltro/logger": "0.86.0",
44
- "@voltro/protocol": "0.86.0",
45
- "jose": "^6.2.12"
61
+ "@voltro/database": "0.88.0",
62
+ "@voltro/env": "0.88.0",
63
+ "@voltro/logger": "0.88.0",
64
+ "@voltro/protocol": "0.88.0",
65
+ "jose": "^6.2.13"
46
66
  },
47
67
  "peerDependencies": {
48
- "effect": "4.0.1"
68
+ "effect": "4.1.0"
49
69
  },
50
70
  "publishConfig": {
51
71
  "access": "public"
package/dist/refresh.js DELETED
@@ -1,57 +0,0 @@
1
- //#region src/refresh.ts
2
- var e = async (e, t = {}) => {
3
- try {
4
- let n = await fetch(e, {
5
- headers: t,
6
- redirect: "error",
7
- signal: AbortSignal.timeout(1e4)
8
- });
9
- if (!n.ok) return await n.body?.cancel(), {
10
- kind: "refused",
11
- reason: "http",
12
- status: n.status
13
- };
14
- if (n.body === null) return {
15
- kind: "refused",
16
- reason: "response"
17
- };
18
- let r = n.body.getReader(), i = new TextDecoder("utf-8", { fatal: !0 }), a = 0, o = "";
19
- try {
20
- for (;;) {
21
- let e = await r.read();
22
- if (e.done) break;
23
- if (a += e.value.byteLength, a > 65536) return await r.cancel(), {
24
- kind: "refused",
25
- reason: "response"
26
- };
27
- o += i.decode(e.value, { stream: !0 });
28
- }
29
- o += i.decode();
30
- } finally {
31
- r.releaseLock();
32
- }
33
- let s;
34
- try {
35
- s = JSON.parse(o);
36
- } catch {
37
- return {
38
- kind: "refused",
39
- reason: "response"
40
- };
41
- }
42
- return typeof s != "object" || !s || Array.isArray(s) || !("token" in s) || typeof s.token != "string" || s.token.trim() === "" ? {
43
- kind: "refused",
44
- reason: "response"
45
- } : {
46
- kind: "token",
47
- token: s.token
48
- };
49
- } catch {
50
- return {
51
- kind: "refused",
52
- reason: "transport"
53
- };
54
- }
55
- };
56
- //#endregion
57
- export { e as fetchLicenseSnapshot };