@voltro/plugin-licensing 0.80.0 → 0.82.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 +1610 -6
- package/THIRD-PARTY-NOTICES.md +1 -1
- package/dist/index.d.ts +37 -2
- package/dist/index.js +37 -11
- package/package.json +5 -5
package/THIRD-PARTY-NOTICES.md
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -38,10 +38,10 @@ export declare interface LicenseClaims {
|
|
|
38
38
|
|
|
39
39
|
export declare const LicenseService: Tag<LicenseServiceShape, LicenseServiceShape>;
|
|
40
40
|
|
|
41
|
-
/** The service handlers can `yield*` to read the current license directly (for
|
|
42
|
-
* feature checks beyond billing's metered entitlements). */
|
|
43
41
|
export declare interface LicenseServiceShape {
|
|
44
42
|
readonly snapshot: () => LicenseSnapshot | undefined;
|
|
43
|
+
/** Where the installation stands with its license — see {@link LicenseStatus}. */
|
|
44
|
+
readonly status: () => LicenseStatus;
|
|
45
45
|
readonly limitFor: (tenantId: string | null | undefined, key: string) => number | undefined;
|
|
46
46
|
readonly hasFeature: (feature: string) => boolean;
|
|
47
47
|
readonly allowsPlugin: (plugin: string) => boolean;
|
|
@@ -62,8 +62,43 @@ export declare interface LicenseSnapshot {
|
|
|
62
62
|
/** Whether a plugin is licensed for production use (name without the
|
|
63
63
|
* `@voltro/plugin-` prefix, e.g. `'storage'`). The "installed ≠ billable" gate. */
|
|
64
64
|
readonly allowsPlugin: (plugin: string) => boolean;
|
|
65
|
+
/** `active` until `exp`, `grace` while an expired license is still honored,
|
|
66
|
+
* `expired` after — when `limitFor` and the rest go dark. */
|
|
67
|
+
readonly state: () => 'active' | 'grace' | 'expired';
|
|
65
68
|
}
|
|
66
69
|
|
|
70
|
+
/** The service handlers can `yield*` to read the current license directly (for
|
|
71
|
+
* feature checks beyond billing's metered entitlements). */
|
|
72
|
+
/**
|
|
73
|
+
* Where the installation stands with its license, for an operator's screen:
|
|
74
|
+
* `none` — no license configured; `active` / `grace` / `expired` — the
|
|
75
|
+
* installed one, by its expiry and the grace period; `rejected` — the license
|
|
76
|
+
* offered did not verify (a last good one, if any, still reports its own
|
|
77
|
+
* state in `installed`).
|
|
78
|
+
*/
|
|
79
|
+
export declare type LicenseStatus = {
|
|
80
|
+
readonly state: 'none';
|
|
81
|
+
} | {
|
|
82
|
+
readonly state: 'active' | 'grace' | 'expired';
|
|
83
|
+
readonly edition: string;
|
|
84
|
+
/** Unix seconds; 0 for a license that does not expire. */
|
|
85
|
+
readonly expiresAt: number;
|
|
86
|
+
/** The tenant a tenant-scoped license applies to. */
|
|
87
|
+
readonly tenant?: string;
|
|
88
|
+
} | {
|
|
89
|
+
readonly state: 'rejected';
|
|
90
|
+
readonly reason: LicenseVerifyError['reason'];
|
|
91
|
+
readonly message: string;
|
|
92
|
+
readonly installed?: {
|
|
93
|
+
readonly state: 'active' | 'grace' | 'expired';
|
|
94
|
+
readonly edition: string;
|
|
95
|
+
readonly expiresAt: number;
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
/** The current {@link LicenseStatus}, read from the in-memory snapshot and the last refusal. */
|
|
100
|
+
export declare const licenseStatus: () => LicenseStatus;
|
|
101
|
+
|
|
67
102
|
export declare class LicenseVerifyError extends LicenseVerifyError_base<{
|
|
68
103
|
/** `expired` — past `exp`; `invalid` — bad signature; `key` — unusable public
|
|
69
104
|
* key; `malformed` — verified but the payload isn't a license. */
|
package/dist/index.js
CHANGED
|
@@ -56,6 +56,7 @@ var c = class extends e.TaggedError("LicenseVerifyError") {}, l = (e) => typeof
|
|
|
56
56
|
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;
|
|
57
57
|
return {
|
|
58
58
|
claims: e,
|
|
59
|
+
state: () => e.exp <= 0 || a() <= e.exp ? "active" : o() ? "grace" : "expired",
|
|
59
60
|
limitFor: (t, n) => {
|
|
60
61
|
if (!o() || e.tenant !== void 0 && e.tenant !== t) return;
|
|
61
62
|
let r = e.entitlements[n];
|
|
@@ -66,10 +67,29 @@ var c = class extends e.TaggedError("LicenseVerifyError") {}, l = (e) => typeof
|
|
|
66
67
|
};
|
|
67
68
|
}, h, g = (e) => {
|
|
68
69
|
h = e;
|
|
69
|
-
}, _ = () => h, v = (e
|
|
70
|
+
}, _ = () => h, v, y = (e) => {
|
|
71
|
+
v = e;
|
|
72
|
+
}, b = () => v, x = (e, n) => t.sync(() => {
|
|
70
73
|
let t = _()?.limitFor(e, n);
|
|
71
74
|
return t === void 0 ? null : t;
|
|
72
|
-
}),
|
|
75
|
+
}), S = () => {
|
|
76
|
+
let e = _(), t = e === void 0 ? void 0 : {
|
|
77
|
+
state: e.state(),
|
|
78
|
+
edition: e.claims.edition,
|
|
79
|
+
expiresAt: e.claims.exp,
|
|
80
|
+
...e.claims.tenant === void 0 ? {} : { tenant: e.claims.tenant }
|
|
81
|
+
}, n = b();
|
|
82
|
+
return n === void 0 ? t ?? { state: "none" } : {
|
|
83
|
+
state: "rejected",
|
|
84
|
+
reason: n.reason,
|
|
85
|
+
message: n.message,
|
|
86
|
+
...t === void 0 ? {} : { installed: {
|
|
87
|
+
state: t.state,
|
|
88
|
+
edition: t.edition,
|
|
89
|
+
expiresAt: t.expiresAt
|
|
90
|
+
} }
|
|
91
|
+
};
|
|
92
|
+
}, C = a([{
|
|
73
93
|
name: "VOLTRO_LICENSE_PUBLIC_KEY",
|
|
74
94
|
required: !1,
|
|
75
95
|
secret: !1,
|
|
@@ -79,23 +99,27 @@ var c = class extends e.TaggedError("LicenseVerifyError") {}, l = (e) => typeof
|
|
|
79
99
|
required: !1,
|
|
80
100
|
secret: !1,
|
|
81
101
|
description: "The signed EdDSA license token, verified offline at boot."
|
|
82
|
-
}]), { Tag:
|
|
102
|
+
}]), { Tag: w, Live: T } = r("@voltro/plugin-licensing/LicenseService", {
|
|
83
103
|
snapshot: () => _(),
|
|
104
|
+
status: () => S(),
|
|
84
105
|
limitFor: (e, t) => _()?.limitFor(e, t),
|
|
85
106
|
hasFeature: (e) => _()?.hasFeature(e) ?? !1,
|
|
86
107
|
allowsPlugin: (e) => _()?.allowsPlugin(e) ?? !1,
|
|
87
108
|
edition: () => _()?.claims.edition
|
|
88
|
-
}),
|
|
89
|
-
let r =
|
|
109
|
+
}), E = class extends e.TaggedError("PluginNotLicensed") {}, D = (e) => _()?.allowsPlugin(e) ?? !1, O = (e) => D(e) ? t.void : t.fail(new E({ plugin: e })), k = (e = {}) => {
|
|
110
|
+
let r = C.read("VOLTRO_LICENSE_PUBLIC_KEY", e.publicKey), a = C.read("VOLTRO_LICENSE_KEY", e.licenseKey), o = e.graceSeconds ?? 0, s = e.refreshMs ?? 9e5, c, l = (e, n) => p(e, n).pipe(t.match({
|
|
90
111
|
onSuccess: (e) => {
|
|
91
|
-
g(m(e, { graceSeconds: o })), c?.info("license active", {
|
|
112
|
+
g(m(e, { graceSeconds: o })), y(void 0), c?.info("license active", {
|
|
92
113
|
edition: e.edition,
|
|
93
114
|
entitlements: Object.keys(e.entitlements).length,
|
|
94
115
|
exp: e.exp
|
|
95
116
|
});
|
|
96
117
|
},
|
|
97
118
|
onFailure: (e) => {
|
|
98
|
-
|
|
119
|
+
y({
|
|
120
|
+
reason: e.reason,
|
|
121
|
+
message: e.message
|
|
122
|
+
}), c?.warn("license verification failed — entitlements fall back to static plan", {
|
|
99
123
|
reason: e.reason,
|
|
100
124
|
message: e.message
|
|
101
125
|
});
|
|
@@ -107,8 +131,8 @@ var c = class extends e.TaggedError("LicenseVerifyError") {}, l = (e) => typeof
|
|
|
107
131
|
instance: e.name
|
|
108
132
|
}),
|
|
109
133
|
description: "Offline-verified EdDSA license keys + entitlement snapshots; feeds @voltro/plugin-billing via entitlementResolver.",
|
|
110
|
-
declaredEnv:
|
|
111
|
-
services:
|
|
134
|
+
declaredEnv: C.declared,
|
|
135
|
+
services: T,
|
|
112
136
|
onActivate: (e) => t.gen(function* () {
|
|
113
137
|
if (c = e.logger, r === void 0 || a === void 0) {
|
|
114
138
|
e.logger.debug("licensing: no license configured — static plan entitlements apply");
|
|
@@ -131,8 +155,10 @@ var c = class extends e.TaggedError("LicenseVerifyError") {}, l = (e) => typeof
|
|
|
131
155
|
}
|
|
132
156
|
});
|
|
133
157
|
},
|
|
134
|
-
onDeactivate: () => t.sync(() =>
|
|
158
|
+
onDeactivate: () => t.sync(() => {
|
|
159
|
+
g(void 0), y(void 0);
|
|
160
|
+
})
|
|
135
161
|
});
|
|
136
162
|
};
|
|
137
163
|
//#endregion
|
|
138
|
-
export {
|
|
164
|
+
export { w as LicenseService, c as LicenseVerifyError, E as PluginNotLicensed, x as entitlementResolver, D as licenseAllowsPlugin, S as licenseStatus, k as licensingPlugin, O as requireLicensedPlugin, p as verifyLicense };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voltro/plugin-licensing",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.82.0",
|
|
4
4
|
"description": "Offline-verified license keys + cloud-issued entitlement snapshots for @voltro apps",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"voltro",
|
|
@@ -38,10 +38,10 @@
|
|
|
38
38
|
"node": ">=24.0.0"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@voltro/database": "0.
|
|
42
|
-
"@voltro/env": "0.
|
|
43
|
-
"@voltro/logger": "0.
|
|
44
|
-
"@voltro/protocol": "0.
|
|
41
|
+
"@voltro/database": "0.82.0",
|
|
42
|
+
"@voltro/env": "0.82.0",
|
|
43
|
+
"@voltro/logger": "0.82.0",
|
|
44
|
+
"@voltro/protocol": "0.82.0",
|
|
45
45
|
"jose": "^6.2.12"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|