@moonbase.sh/licensing 0.0.0-next-20260729150401
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/FINGERPRINT_SPEC.md +414 -0
- package/README.md +243 -0
- package/dist/index.cjs +925 -0
- package/dist/index.d.cts +634 -0
- package/dist/index.d.ts +634 -0
- package/dist/index.js +863 -0
- package/fingerprint-vectors.json +744 -0
- package/package.json +40 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,925 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
ActivationMethod: () => ActivationMethod,
|
|
34
|
+
ErrorType: () => ErrorType,
|
|
35
|
+
FINGERPRINT_PREFIX: () => FINGERPRINT_PREFIX,
|
|
36
|
+
FINGERPRINT_VERSION: () => FINGERPRINT_VERSION,
|
|
37
|
+
FileLicenseStore: () => FileLicenseStore,
|
|
38
|
+
IDENTIFYING_PARAM_NAMES: () => IDENTIFYING_PARAM_NAMES,
|
|
39
|
+
InMemoryLicenseStore: () => InMemoryLicenseStore,
|
|
40
|
+
InsufficientDeviceIdentityError: () => InsufficientDeviceIdentityError,
|
|
41
|
+
LegacyDeviceIdResolver: () => LegacyDeviceIdResolver,
|
|
42
|
+
LicenseClient: () => LicenseClient,
|
|
43
|
+
LicenseValidator: () => LicenseValidator,
|
|
44
|
+
MAX_VALUE_LENGTH: () => MAX_VALUE_LENGTH,
|
|
45
|
+
MigratingDeviceIdResolver: () => MigratingDeviceIdResolver,
|
|
46
|
+
MoonbaseDeviceIdResolver: () => MoonbaseDeviceIdResolver,
|
|
47
|
+
MoonbaseError: () => MoonbaseError,
|
|
48
|
+
MoonbaseLicensing: () => MoonbaseLicensing,
|
|
49
|
+
buildFingerprintMaterial: () => buildFingerprintMaterial,
|
|
50
|
+
canonicalizeParams: () => canonicalizeParams,
|
|
51
|
+
canonicalizeValue: () => canonicalizeValue,
|
|
52
|
+
defaultDeviceIdentityReader: () => defaultDeviceIdentityReader,
|
|
53
|
+
fingerprintDeviceId: () => fingerprintDeviceId,
|
|
54
|
+
fingerprintDigest: () => fingerprintDigest,
|
|
55
|
+
parseDeviceIdStamp: () => parseDeviceIdStamp,
|
|
56
|
+
parseIoregPlatformUuid: () => parseIoregPlatformUuid,
|
|
57
|
+
parseSmbiosParams: () => parseSmbiosParams,
|
|
58
|
+
platformTag: () => platformTag,
|
|
59
|
+
selectMachineId: () => selectMachineId,
|
|
60
|
+
stampDeviceId: () => stampDeviceId
|
|
61
|
+
});
|
|
62
|
+
module.exports = __toCommonJS(index_exports);
|
|
63
|
+
var import_node_buffer2 = require("buffer");
|
|
64
|
+
var import_node_process3 = __toESM(require("process"), 1);
|
|
65
|
+
|
|
66
|
+
// src/client.ts
|
|
67
|
+
var import_cross_fetch = __toESM(require("cross-fetch"), 1);
|
|
68
|
+
|
|
69
|
+
// src/schemas.ts
|
|
70
|
+
var import_zod = require("zod");
|
|
71
|
+
|
|
72
|
+
// src/types.ts
|
|
73
|
+
var ActivationMethod = /* @__PURE__ */ ((ActivationMethod2) => {
|
|
74
|
+
ActivationMethod2["Online"] = "Online";
|
|
75
|
+
ActivationMethod2["Offline"] = "Offline";
|
|
76
|
+
return ActivationMethod2;
|
|
77
|
+
})(ActivationMethod || {});
|
|
78
|
+
|
|
79
|
+
// src/schemas.ts
|
|
80
|
+
var activationRequestResponseSchema = import_zod.z.object({
|
|
81
|
+
id: import_zod.z.string(),
|
|
82
|
+
request: import_zod.z.string(),
|
|
83
|
+
browser: import_zod.z.string()
|
|
84
|
+
});
|
|
85
|
+
var productSchema = import_zod.z.object({
|
|
86
|
+
id: import_zod.z.string(),
|
|
87
|
+
name: import_zod.z.string(),
|
|
88
|
+
currentReleaseVersion: import_zod.z.string().nullish(),
|
|
89
|
+
properties: import_zod.z.record(import_zod.z.unknown()).nullish()
|
|
90
|
+
});
|
|
91
|
+
var userSchema = import_zod.z.object({
|
|
92
|
+
id: import_zod.z.string(),
|
|
93
|
+
name: import_zod.z.string(),
|
|
94
|
+
email: import_zod.z.string(),
|
|
95
|
+
properties: import_zod.z.record(import_zod.z.unknown()).nullish()
|
|
96
|
+
});
|
|
97
|
+
var licenseSchema = import_zod.z.object({
|
|
98
|
+
id: import_zod.z.string(),
|
|
99
|
+
trial: import_zod.z.boolean(),
|
|
100
|
+
activationMethod: import_zod.z.nativeEnum(ActivationMethod),
|
|
101
|
+
product: productSchema,
|
|
102
|
+
ownedSubProductIds: import_zod.z.array(import_zod.z.string()).default([]),
|
|
103
|
+
subscriptionId: import_zod.z.string().nullish(),
|
|
104
|
+
issuedAt: import_zod.z.coerce.date(),
|
|
105
|
+
issuedTo: userSchema,
|
|
106
|
+
expiresAt: import_zod.z.coerce.date().nullish(),
|
|
107
|
+
validatedAt: import_zod.z.coerce.date(),
|
|
108
|
+
properties: import_zod.z.record(import_zod.z.unknown()).nullish(),
|
|
109
|
+
token: import_zod.z.string()
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// src/client.ts
|
|
113
|
+
var defaultFetchOptions = {
|
|
114
|
+
method: "GET",
|
|
115
|
+
mode: "cors",
|
|
116
|
+
headers: {
|
|
117
|
+
"Accept": "application/json",
|
|
118
|
+
"Content-Type": "application/json",
|
|
119
|
+
"x-mb-client": `moonbase.js`
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
var LicenseClient = class {
|
|
123
|
+
constructor(configuration, deviceIdResolver, licenseValidator) {
|
|
124
|
+
this.configuration = configuration;
|
|
125
|
+
this.deviceIdResolver = deviceIdResolver;
|
|
126
|
+
this.licenseValidator = licenseValidator;
|
|
127
|
+
}
|
|
128
|
+
async requestActivation() {
|
|
129
|
+
const content = {
|
|
130
|
+
deviceName: await this.deviceIdResolver.resolveDeviceName(),
|
|
131
|
+
deviceSignature: await this.deviceIdResolver.resolveDeviceId()
|
|
132
|
+
};
|
|
133
|
+
const response = await (0, import_cross_fetch.default)(`${this.configuration.endpoint}/api/client/activations/${this.configuration.productId}/request${this.buildQueryString()}`, {
|
|
134
|
+
...defaultFetchOptions,
|
|
135
|
+
method: "POST",
|
|
136
|
+
body: JSON.stringify(content)
|
|
137
|
+
});
|
|
138
|
+
if (response.status >= 400) {
|
|
139
|
+
throw new MoonbaseError("Request not successful", `The API responded with a ${response.status} ${response.statusText} response`, "ApiError" /* ApiError */);
|
|
140
|
+
}
|
|
141
|
+
try {
|
|
142
|
+
return activationRequestResponseSchema.parse(await response.json());
|
|
143
|
+
} catch (err) {
|
|
144
|
+
const error = err;
|
|
145
|
+
throw new MoonbaseError(
|
|
146
|
+
"Could not request activation",
|
|
147
|
+
error.message,
|
|
148
|
+
"ApiError" /* ApiError */,
|
|
149
|
+
error
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
async getRequestedActivation(request) {
|
|
154
|
+
const response = await (0, import_cross_fetch.default)(request.request, defaultFetchOptions);
|
|
155
|
+
if (response.status === 204 || response.status === 404)
|
|
156
|
+
return null;
|
|
157
|
+
return await this.handleLicenseResponse(response);
|
|
158
|
+
}
|
|
159
|
+
async requestTrial() {
|
|
160
|
+
const content = {
|
|
161
|
+
deviceName: await this.deviceIdResolver.resolveDeviceName(),
|
|
162
|
+
deviceSignature: await this.deviceIdResolver.resolveDeviceId()
|
|
163
|
+
};
|
|
164
|
+
const response = await (0, import_cross_fetch.default)(`${this.configuration.endpoint}/api/client/trials/${this.configuration.productId}/request${this.buildQueryString()}`, {
|
|
165
|
+
...defaultFetchOptions,
|
|
166
|
+
method: "POST",
|
|
167
|
+
headers: {
|
|
168
|
+
...defaultFetchOptions.headers,
|
|
169
|
+
"Content-Type": "application/json"
|
|
170
|
+
},
|
|
171
|
+
body: JSON.stringify(content)
|
|
172
|
+
});
|
|
173
|
+
return await this.handleLicenseResponse(response);
|
|
174
|
+
}
|
|
175
|
+
async validateLicense(license) {
|
|
176
|
+
const response = await (0, import_cross_fetch.default)(`${this.configuration.endpoint}/api/client/licenses/${this.configuration.productId}/validate${this.buildQueryString()}`, {
|
|
177
|
+
...defaultFetchOptions,
|
|
178
|
+
method: "POST",
|
|
179
|
+
headers: {
|
|
180
|
+
...defaultFetchOptions.headers,
|
|
181
|
+
"Content-Type": "text/plain"
|
|
182
|
+
},
|
|
183
|
+
body: license.token
|
|
184
|
+
});
|
|
185
|
+
return await this.handleLicenseResponse(response);
|
|
186
|
+
}
|
|
187
|
+
async validateRawLicense(rawLicense) {
|
|
188
|
+
const license = await this.licenseValidator.validateLicense(rawLicense.toString("utf8"));
|
|
189
|
+
if (license.activationMethod === "Offline" /* Offline */)
|
|
190
|
+
return license;
|
|
191
|
+
return await this.validateLicense(license);
|
|
192
|
+
}
|
|
193
|
+
async revokeLicense(license) {
|
|
194
|
+
const response = await (0, import_cross_fetch.default)(`${this.configuration.endpoint}/api/client/licenses/${this.configuration.productId}/revoke?format=JWT`, {
|
|
195
|
+
...defaultFetchOptions,
|
|
196
|
+
method: "POST",
|
|
197
|
+
headers: {
|
|
198
|
+
...defaultFetchOptions.headers,
|
|
199
|
+
"Content-Type": "text/plain"
|
|
200
|
+
},
|
|
201
|
+
body: license.token
|
|
202
|
+
});
|
|
203
|
+
if (response.status >= 400) {
|
|
204
|
+
throw new MoonbaseError("Request not successful", `The API responded with a ${response.status} ${response.statusText} response`, "ApiError" /* ApiError */);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
async handleLicenseResponse(response) {
|
|
208
|
+
if (response.status >= 400) {
|
|
209
|
+
throw new MoonbaseError("Request not successful", `The API responded with a ${response.status} ${response.statusText} response`, "ApiError" /* ApiError */);
|
|
210
|
+
}
|
|
211
|
+
return await this.licenseValidator.validateLicense(await response.text());
|
|
212
|
+
}
|
|
213
|
+
buildQueryString() {
|
|
214
|
+
const parts = ["format=JWT"];
|
|
215
|
+
const { platform, appVersion, metadata } = this.configuration;
|
|
216
|
+
if (platform)
|
|
217
|
+
parts.push(`platform=${encodeURIComponent(platform)}`);
|
|
218
|
+
if (appVersion)
|
|
219
|
+
parts.push(`appVersion=${encodeURIComponent(appVersion)}`);
|
|
220
|
+
if (metadata) {
|
|
221
|
+
for (const [key, value] of Object.entries(metadata)) {
|
|
222
|
+
if (value === null || value === void 0 || value === "")
|
|
223
|
+
continue;
|
|
224
|
+
parts.push(`meta[${encodeURIComponent(key)}]=${encodeURIComponent(value)}`);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return `?${parts.join("&")}`;
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
// src/deviceIdResolver.ts
|
|
232
|
+
var import_node_child_process2 = __toESM(require("child_process"), 1);
|
|
233
|
+
var import_node_crypto2 = require("crypto");
|
|
234
|
+
var import_node_os2 = __toESM(require("os"), 1);
|
|
235
|
+
var import_node_process2 = __toESM(require("process"), 1);
|
|
236
|
+
var import_systeminformation = __toESM(require("systeminformation"), 1);
|
|
237
|
+
|
|
238
|
+
// src/errors.ts
|
|
239
|
+
var ErrorType = /* @__PURE__ */ ((ErrorType2) => {
|
|
240
|
+
ErrorType2["None"] = "None";
|
|
241
|
+
ErrorType2["ApiError"] = "ApiError";
|
|
242
|
+
ErrorType2["NoEligibleLicense"] = "NoEligibleLicense";
|
|
243
|
+
ErrorType2["LicenseInvalid"] = "LicenseInvalid";
|
|
244
|
+
ErrorType2["LicenseRevoked"] = "LicenseRevoked";
|
|
245
|
+
ErrorType2["LicenseActivationRevoked"] = "LicenseActivationRevoked";
|
|
246
|
+
ErrorType2["LicenseExpired"] = "LicenseExpired";
|
|
247
|
+
ErrorType2["LicenseDeviceMismatch"] = "LicenseDeviceMismatch";
|
|
248
|
+
ErrorType2["DeviceIdentityUnavailable"] = "DeviceIdentityUnavailable";
|
|
249
|
+
return ErrorType2;
|
|
250
|
+
})(ErrorType || {});
|
|
251
|
+
var MoonbaseError = class extends Error {
|
|
252
|
+
constructor(title, detail, type, inner) {
|
|
253
|
+
super();
|
|
254
|
+
this.title = title;
|
|
255
|
+
this.detail = detail;
|
|
256
|
+
this.type = type;
|
|
257
|
+
this.inner = inner;
|
|
258
|
+
this.name = "MoonbaseError";
|
|
259
|
+
this.message = detail != null ? detail : title;
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
var InsufficientDeviceIdentityError = class extends MoonbaseError {
|
|
263
|
+
constructor(platform, reason = "no identity parameter could be read") {
|
|
264
|
+
super(
|
|
265
|
+
"No device identity",
|
|
266
|
+
`Could not identify this device (platform: ${platform}): ${reason}`,
|
|
267
|
+
"DeviceIdentityUnavailable" /* DeviceIdentityUnavailable */
|
|
268
|
+
);
|
|
269
|
+
this.platform = platform;
|
|
270
|
+
this.name = "InsufficientDeviceIdentityError";
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
// src/fingerprint.ts
|
|
275
|
+
var import_node_buffer = require("buffer");
|
|
276
|
+
var import_node_child_process = __toESM(require("child_process"), 1);
|
|
277
|
+
var import_node_crypto = require("crypto");
|
|
278
|
+
var import_node_fs = __toESM(require("fs"), 1);
|
|
279
|
+
var import_node_os = __toESM(require("os"), 1);
|
|
280
|
+
var import_node_process = __toESM(require("process"), 1);
|
|
281
|
+
var FINGERPRINT_PREFIX = "moonbase:fingerprint:v2";
|
|
282
|
+
var FINGERPRINT_VERSION = 2;
|
|
283
|
+
var MAX_VALUE_LENGTH = 128;
|
|
284
|
+
var PRINTABLE_ASCII_MIN = 32;
|
|
285
|
+
var PRINTABLE_ASCII_MAX = 126;
|
|
286
|
+
var STAMP_PATTERN = /^mbd(\d+)(n?)_([0-9a-f]{64})$/;
|
|
287
|
+
function canonicalizeValue(value) {
|
|
288
|
+
var _a;
|
|
289
|
+
let printable = "";
|
|
290
|
+
for (const char of value.normalize("NFC")) {
|
|
291
|
+
const code = (_a = char.codePointAt(0)) != null ? _a : 0;
|
|
292
|
+
if (code >= PRINTABLE_ASCII_MIN && code <= PRINTABLE_ASCII_MAX)
|
|
293
|
+
printable += char;
|
|
294
|
+
}
|
|
295
|
+
return printable.slice(0, MAX_VALUE_LENGTH).replace(/^ +| +$/g, "");
|
|
296
|
+
}
|
|
297
|
+
function platformTag(platform = import_node_process.default.platform) {
|
|
298
|
+
switch (platform) {
|
|
299
|
+
case "darwin":
|
|
300
|
+
return "mac";
|
|
301
|
+
case "win32":
|
|
302
|
+
return "windows";
|
|
303
|
+
case "android":
|
|
304
|
+
return "android";
|
|
305
|
+
case "linux":
|
|
306
|
+
return "linux";
|
|
307
|
+
case "freebsd":
|
|
308
|
+
case "openbsd":
|
|
309
|
+
case "netbsd":
|
|
310
|
+
return "bsd";
|
|
311
|
+
default:
|
|
312
|
+
return "unknown";
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
var IDENTIFYING_PARAMS = /* @__PURE__ */ new Set([
|
|
316
|
+
"ioPlatformUuid",
|
|
317
|
+
"machineId",
|
|
318
|
+
"systemUuid",
|
|
319
|
+
"baseboardSerialNumber",
|
|
320
|
+
"deviceName"
|
|
321
|
+
]);
|
|
322
|
+
var IDENTIFYING_PARAM_NAMES = Object.freeze([...IDENTIFYING_PARAMS]);
|
|
323
|
+
var NOT_PROGRAMMED_VALUES = /* @__PURE__ */ new Set([
|
|
324
|
+
"to be filled by o.e.m.",
|
|
325
|
+
// The same filler without the dots, which plenty of firmware writes instead.
|
|
326
|
+
"to be filled by oem",
|
|
327
|
+
"default string",
|
|
328
|
+
"system serial number",
|
|
329
|
+
"base board serial number",
|
|
330
|
+
"chassis serial number",
|
|
331
|
+
"not specified",
|
|
332
|
+
"not applicable",
|
|
333
|
+
"not available",
|
|
334
|
+
"none",
|
|
335
|
+
"unknown",
|
|
336
|
+
"invalid",
|
|
337
|
+
"n/a",
|
|
338
|
+
"0123456789",
|
|
339
|
+
// `machine-id(5)`: the literal marker systemd writes to say "no id yet",
|
|
340
|
+
// e.g. in an initrd or a golden image awaiting first boot. Every machine
|
|
341
|
+
// deployed from such an image reads it, so it is the opposite of an identifier.
|
|
342
|
+
"uninitialized"
|
|
343
|
+
]);
|
|
344
|
+
function isNotProgrammed(value) {
|
|
345
|
+
return NOT_PROGRAMMED_VALUES.has(value.toLowerCase()) || /^0+$/.test(value) || /^f+$/i.test(value);
|
|
346
|
+
}
|
|
347
|
+
function canonicalizeParams(params) {
|
|
348
|
+
const kept = [];
|
|
349
|
+
const seen = /* @__PURE__ */ new Set();
|
|
350
|
+
for (const [name, rawValue] of params) {
|
|
351
|
+
const value = canonicalizeValue(rawValue);
|
|
352
|
+
if (value.length === 0)
|
|
353
|
+
continue;
|
|
354
|
+
if (IDENTIFYING_PARAMS.has(name) && isNotProgrammed(value))
|
|
355
|
+
continue;
|
|
356
|
+
if (seen.has(name))
|
|
357
|
+
throw new Error(`Duplicate fingerprint parameter name: ${name}`);
|
|
358
|
+
seen.add(name);
|
|
359
|
+
kept.push([name, value]);
|
|
360
|
+
}
|
|
361
|
+
return kept;
|
|
362
|
+
}
|
|
363
|
+
function buildFingerprintMaterial(platform, params) {
|
|
364
|
+
const kept = canonicalizeParams(params);
|
|
365
|
+
if (kept.length === 0)
|
|
366
|
+
throw new InsufficientDeviceIdentityError(platform, "no identity parameter could be read");
|
|
367
|
+
if (!kept.some(([name]) => IDENTIFYING_PARAMS.has(name))) {
|
|
368
|
+
throw new InsufficientDeviceIdentityError(
|
|
369
|
+
platform,
|
|
370
|
+
`only model-level parameters could be read (${kept.map(([name]) => name).join(", ")}), none of which identify this individual machine`
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
const lines = [FINGERPRINT_PREFIX, `platform=${platform}`];
|
|
374
|
+
for (const [name, value] of kept)
|
|
375
|
+
lines.push(`${name}=${value}`);
|
|
376
|
+
return lines.join("\n");
|
|
377
|
+
}
|
|
378
|
+
function fingerprintDigest(material) {
|
|
379
|
+
return (0, import_node_crypto.createHash)("sha256").update(material, "utf8").digest("hex");
|
|
380
|
+
}
|
|
381
|
+
function stampDeviceId(digest, source = "identity") {
|
|
382
|
+
return `mbd${FINGERPRINT_VERSION}${source === "deviceName" ? "n" : ""}_${digest}`;
|
|
383
|
+
}
|
|
384
|
+
function fingerprintDeviceId(material, source = "identity") {
|
|
385
|
+
return stampDeviceId(fingerprintDigest(material), source);
|
|
386
|
+
}
|
|
387
|
+
function parseDeviceIdStamp(deviceId) {
|
|
388
|
+
const match = STAMP_PATTERN.exec(deviceId);
|
|
389
|
+
if (!match)
|
|
390
|
+
return null;
|
|
391
|
+
return {
|
|
392
|
+
version: Number(match[1]),
|
|
393
|
+
source: match[2] === "n" ? "deviceName" : "identity",
|
|
394
|
+
digest: match[3]
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
function commandOutput(command) {
|
|
398
|
+
try {
|
|
399
|
+
return import_node_child_process.default.execSync(command, { encoding: "utf8" });
|
|
400
|
+
} catch (e) {
|
|
401
|
+
return "";
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
function readSysFile(path2) {
|
|
405
|
+
try {
|
|
406
|
+
return import_node_fs.default.readFileSync(path2, "utf8");
|
|
407
|
+
} catch (e) {
|
|
408
|
+
return "";
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
function parseIoregPlatformUuid(ioregOutput) {
|
|
412
|
+
const match = ioregOutput.match(/"IOPlatformUUID"\s*=\s*"([^"]+)"/);
|
|
413
|
+
return match ? match[1].replaceAll("-", "").toUpperCase() : "";
|
|
414
|
+
}
|
|
415
|
+
function readMacIdentity() {
|
|
416
|
+
const uuid = parseIoregPlatformUuid(commandOutput("ioreg -rd1 -c IOPlatformExpertDevice"));
|
|
417
|
+
const params = [["ioPlatformUuid", uuid]];
|
|
418
|
+
return { params, deviceName: import_node_os.default.hostname().replace(/\.local$/i, "") };
|
|
419
|
+
}
|
|
420
|
+
function selectMachineId(...sources) {
|
|
421
|
+
var _a;
|
|
422
|
+
return (_a = sources.map(canonicalizeValue).find((value) => /^[0-9a-f]{32}$/.test(value) && !isNotProgrammed(value))) != null ? _a : "";
|
|
423
|
+
}
|
|
424
|
+
function readMachineId() {
|
|
425
|
+
return selectMachineId(
|
|
426
|
+
readSysFile("/etc/machine-id"),
|
|
427
|
+
readSysFile("/var/lib/dbus/machine-id")
|
|
428
|
+
);
|
|
429
|
+
}
|
|
430
|
+
function readLinuxIdentity() {
|
|
431
|
+
const params = [
|
|
432
|
+
["machineId", readMachineId()],
|
|
433
|
+
["sysVendor", readSysFile("/sys/class/dmi/id/sys_vendor")],
|
|
434
|
+
["productName", readSysFile("/sys/class/dmi/id/product_name")],
|
|
435
|
+
["boardVendor", readSysFile("/sys/class/dmi/id/board_vendor")],
|
|
436
|
+
["boardName", readSysFile("/sys/class/dmi/id/board_name")]
|
|
437
|
+
];
|
|
438
|
+
return { params, deviceName: import_node_os.default.hostname() };
|
|
439
|
+
}
|
|
440
|
+
function parseSmbiosStructures(data) {
|
|
441
|
+
const structures = [];
|
|
442
|
+
let offset = 0;
|
|
443
|
+
while (offset + 4 <= data.length) {
|
|
444
|
+
const type = data[offset];
|
|
445
|
+
const length = data[offset + 1];
|
|
446
|
+
if (length < 4 || offset + length > data.length)
|
|
447
|
+
break;
|
|
448
|
+
const formatted = data.subarray(offset, offset + length);
|
|
449
|
+
const strings = [];
|
|
450
|
+
let p = offset + length;
|
|
451
|
+
if (p + 1 < data.length && data[p] === 0 && data[p + 1] === 0) {
|
|
452
|
+
p += 2;
|
|
453
|
+
} else {
|
|
454
|
+
while (p < data.length) {
|
|
455
|
+
let end = p;
|
|
456
|
+
while (end < data.length && data[end] !== 0)
|
|
457
|
+
end++;
|
|
458
|
+
strings.push(data.toString("latin1", p, end));
|
|
459
|
+
p = end + 1;
|
|
460
|
+
if (p < data.length && data[p] === 0) {
|
|
461
|
+
p += 1;
|
|
462
|
+
break;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
structures.push({ type, formatted, strings });
|
|
467
|
+
if (type === 127)
|
|
468
|
+
break;
|
|
469
|
+
offset = p;
|
|
470
|
+
}
|
|
471
|
+
return structures;
|
|
472
|
+
}
|
|
473
|
+
function resolveSmbiosString(structure, fieldOffset) {
|
|
474
|
+
if (fieldOffset >= structure.formatted.length)
|
|
475
|
+
return "";
|
|
476
|
+
const index = structure.formatted[fieldOffset];
|
|
477
|
+
if (index === 0 || index > structure.strings.length)
|
|
478
|
+
return "";
|
|
479
|
+
return structure.strings[index - 1];
|
|
480
|
+
}
|
|
481
|
+
function formatSmbiosUuid(structure, fieldOffset) {
|
|
482
|
+
if (fieldOffset + 16 > structure.formatted.length)
|
|
483
|
+
return "";
|
|
484
|
+
const bytes = structure.formatted.subarray(fieldOffset, fieldOffset + 16);
|
|
485
|
+
if (bytes.every((byte) => byte === 0) || bytes.every((byte) => byte === 255))
|
|
486
|
+
return "";
|
|
487
|
+
let hex = "";
|
|
488
|
+
for (const byte of bytes)
|
|
489
|
+
hex += byte.toString(16).padStart(2, "0").toUpperCase();
|
|
490
|
+
return hex;
|
|
491
|
+
}
|
|
492
|
+
function parseSmbiosParams(smbiosData) {
|
|
493
|
+
const structures = parseSmbiosStructures(smbiosData);
|
|
494
|
+
const params = [];
|
|
495
|
+
const system = structures.find((structure) => structure.type === 1);
|
|
496
|
+
if (system) {
|
|
497
|
+
params.push(["systemManufacturer", resolveSmbiosString(system, 4)]);
|
|
498
|
+
params.push(["systemProductName", resolveSmbiosString(system, 5)]);
|
|
499
|
+
params.push(["systemUuid", formatSmbiosUuid(system, 8)]);
|
|
500
|
+
}
|
|
501
|
+
const baseboard = structures.find((structure) => structure.type === 2);
|
|
502
|
+
if (baseboard) {
|
|
503
|
+
params.push(["baseboardManufacturer", resolveSmbiosString(baseboard, 4)]);
|
|
504
|
+
params.push(["baseboardProduct", resolveSmbiosString(baseboard, 5)]);
|
|
505
|
+
params.push(["baseboardSerialNumber", resolveSmbiosString(baseboard, 7)]);
|
|
506
|
+
}
|
|
507
|
+
return params;
|
|
508
|
+
}
|
|
509
|
+
function readWindowsSmbios() {
|
|
510
|
+
const script = "[Convert]::ToBase64String((Get-CimInstance -Namespace root/wmi -ClassName MSSmBios_RawSMBiosTables).SMBiosData)";
|
|
511
|
+
const output = commandOutput(`powershell -NoProfile -NonInteractive -Command "${script}"`);
|
|
512
|
+
try {
|
|
513
|
+
return import_node_buffer.Buffer.from(output.trim(), "base64");
|
|
514
|
+
} catch (e) {
|
|
515
|
+
return import_node_buffer.Buffer.alloc(0);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
function readWindowsIdentity() {
|
|
519
|
+
return { params: parseSmbiosParams(readWindowsSmbios()), deviceName: import_node_os.default.hostname() };
|
|
520
|
+
}
|
|
521
|
+
function defaultDeviceIdentityReader(platform = import_node_process.default.platform) {
|
|
522
|
+
return {
|
|
523
|
+
read() {
|
|
524
|
+
switch (platform) {
|
|
525
|
+
case "darwin":
|
|
526
|
+
return readMacIdentity();
|
|
527
|
+
case "linux":
|
|
528
|
+
return readLinuxIdentity();
|
|
529
|
+
case "win32":
|
|
530
|
+
return readWindowsIdentity();
|
|
531
|
+
// android, bsd and anything else define no identity params: the spec
|
|
532
|
+
// has no stable hardware source for them, so they resolve to an
|
|
533
|
+
// insufficient-identity error unless the deviceName fallback is enabled.
|
|
534
|
+
default:
|
|
535
|
+
return { params: [], deviceName: import_node_os.default.hostname() };
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
};
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// src/deviceIdResolver.ts
|
|
542
|
+
var MoonbaseDeviceIdResolver = class {
|
|
543
|
+
constructor(options) {
|
|
544
|
+
var _a, _b, _c;
|
|
545
|
+
const platform = (_a = options == null ? void 0 : options.platform) != null ? _a : import_node_process2.default.platform;
|
|
546
|
+
this.platform = platformTag(platform);
|
|
547
|
+
this.reader = (_b = options == null ? void 0 : options.reader) != null ? _b : defaultDeviceIdentityReader(platform);
|
|
548
|
+
this.fallback = (_c = options == null ? void 0 : options.fallback) != null ? _c : "none";
|
|
549
|
+
}
|
|
550
|
+
async resolveDeviceName() {
|
|
551
|
+
return this.readIdentity().deviceName;
|
|
552
|
+
}
|
|
553
|
+
async resolveDeviceId() {
|
|
554
|
+
return this.compute().deviceId;
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* A fresh copy each call. The device binding is what activation sends and what
|
|
558
|
+
* validation compares, so handing out the resolver's own object would let a
|
|
559
|
+
* consumer that edits a diagnostic — or logs it through something that
|
|
560
|
+
* normalizes in place — silently change the id every later call returns.
|
|
561
|
+
*/
|
|
562
|
+
async describeDevice() {
|
|
563
|
+
const described = this.compute();
|
|
564
|
+
return { ...described, paramNames: [...described.paramNames] };
|
|
565
|
+
}
|
|
566
|
+
compute() {
|
|
567
|
+
var _a;
|
|
568
|
+
(_a = this.described) != null ? _a : this.described = this.computeDescription();
|
|
569
|
+
return this.described;
|
|
570
|
+
}
|
|
571
|
+
/**
|
|
572
|
+
* Read identity at most once. Both halves of an activation request ask for it —
|
|
573
|
+
* the name and then the id — and a read can mean spawning `ioreg` or
|
|
574
|
+
* PowerShell, so reading per call would double the cost of every request and
|
|
575
|
+
* let the name and the id come from two different reads of the machine.
|
|
576
|
+
*/
|
|
577
|
+
readIdentity() {
|
|
578
|
+
var _a;
|
|
579
|
+
(_a = this.identity) != null ? _a : this.identity = this.reader.read();
|
|
580
|
+
return this.identity;
|
|
581
|
+
}
|
|
582
|
+
computeDescription() {
|
|
583
|
+
const { params, deviceName } = this.readIdentity();
|
|
584
|
+
try {
|
|
585
|
+
return this.describe(params, "identity");
|
|
586
|
+
} catch (err) {
|
|
587
|
+
if (this.fallback !== "deviceName" || !(err instanceof InsufficientDeviceIdentityError))
|
|
588
|
+
throw err;
|
|
589
|
+
return this.describe([["deviceName", deviceName]], "deviceName");
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
describe(params, source) {
|
|
593
|
+
return {
|
|
594
|
+
deviceId: fingerprintDeviceId(buildFingerprintMaterial(this.platform, params), source),
|
|
595
|
+
version: FINGERPRINT_VERSION,
|
|
596
|
+
platform: this.platform,
|
|
597
|
+
source,
|
|
598
|
+
paramNames: canonicalizeParams(params).map(([name]) => name)
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
};
|
|
602
|
+
var MigratingDeviceIdResolver = class {
|
|
603
|
+
constructor(current, ...previous) {
|
|
604
|
+
this.current = current;
|
|
605
|
+
this.previous = previous;
|
|
606
|
+
const describe = current.describeDevice;
|
|
607
|
+
if (typeof describe === "function")
|
|
608
|
+
this.describeDevice = () => describe.call(current);
|
|
609
|
+
}
|
|
610
|
+
async resolveDeviceName() {
|
|
611
|
+
return this.current.resolveDeviceName();
|
|
612
|
+
}
|
|
613
|
+
async resolveDeviceId() {
|
|
614
|
+
return this.current.resolveDeviceId();
|
|
615
|
+
}
|
|
616
|
+
async acceptsDeviceId(deviceId) {
|
|
617
|
+
if (!this.previousIds) {
|
|
618
|
+
this.previousIds = Promise.all(this.previous.map(async (resolver) => {
|
|
619
|
+
try {
|
|
620
|
+
return await resolver.resolveDeviceId();
|
|
621
|
+
} catch (e) {
|
|
622
|
+
return "";
|
|
623
|
+
}
|
|
624
|
+
}));
|
|
625
|
+
}
|
|
626
|
+
return (await this.previousIds).some((previous) => previous.length > 0 && previous === deviceId);
|
|
627
|
+
}
|
|
628
|
+
};
|
|
629
|
+
var LegacyDeviceIdResolver = class {
|
|
630
|
+
async resolveDeviceName() {
|
|
631
|
+
switch (import_node_process2.default.platform) {
|
|
632
|
+
case "darwin":
|
|
633
|
+
try {
|
|
634
|
+
return import_node_child_process2.default.execSync("scutil --get ComputerName").toString().trim();
|
|
635
|
+
} catch (e) {
|
|
636
|
+
return import_node_os2.default.hostname();
|
|
637
|
+
}
|
|
638
|
+
case "win32":
|
|
639
|
+
return import_node_process2.default.env.COMPUTERNAME || import_node_os2.default.hostname();
|
|
640
|
+
case "linux": {
|
|
641
|
+
const prettyname = import_node_child_process2.default.execSync("hostnamectl --pretty").toString().trim();
|
|
642
|
+
return prettyname || import_node_os2.default.hostname();
|
|
643
|
+
}
|
|
644
|
+
default:
|
|
645
|
+
return import_node_os2.default.hostname();
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
async resolveDeviceId() {
|
|
649
|
+
const [cpu, hw] = await Promise.all([import_systeminformation.default.cpu(), import_systeminformation.default.system()]);
|
|
650
|
+
const parts = [
|
|
651
|
+
import_node_os2.default.hostname(),
|
|
652
|
+
hw.manufacturer,
|
|
653
|
+
hw.model,
|
|
654
|
+
hw.serial,
|
|
655
|
+
hw.uuid,
|
|
656
|
+
hw.sku,
|
|
657
|
+
cpu.manufacturer,
|
|
658
|
+
cpu.brand,
|
|
659
|
+
cpu.vendor,
|
|
660
|
+
cpu.family,
|
|
661
|
+
cpu.model
|
|
662
|
+
];
|
|
663
|
+
const hash = (0, import_node_crypto2.createHash)("sha256").update(parts.join("")).digest();
|
|
664
|
+
return hash.toString("base64").replaceAll("=", "");
|
|
665
|
+
}
|
|
666
|
+
};
|
|
667
|
+
|
|
668
|
+
// src/store.ts
|
|
669
|
+
var import_node_fs2 = __toESM(require("fs"), 1);
|
|
670
|
+
var import_promises = __toESM(require("fs/promises"), 1);
|
|
671
|
+
var import_node_path = __toESM(require("path"), 1);
|
|
672
|
+
var InMemoryLicenseStore = class {
|
|
673
|
+
async loadLocalLicense() {
|
|
674
|
+
var _a;
|
|
675
|
+
return (_a = this.license) != null ? _a : null;
|
|
676
|
+
}
|
|
677
|
+
async storeLocalLicense(license) {
|
|
678
|
+
this.license = license;
|
|
679
|
+
}
|
|
680
|
+
async deleteLocalLicense() {
|
|
681
|
+
this.license = void 0;
|
|
682
|
+
}
|
|
683
|
+
};
|
|
684
|
+
var FileLicenseStore = class {
|
|
685
|
+
constructor(options) {
|
|
686
|
+
this.options = options;
|
|
687
|
+
}
|
|
688
|
+
async loadLocalLicense() {
|
|
689
|
+
if (!import_node_fs2.default.existsSync(this.path))
|
|
690
|
+
return null;
|
|
691
|
+
try {
|
|
692
|
+
const file = await import_promises.default.readFile(this.path, { encoding: "utf-8" });
|
|
693
|
+
const license = licenseSchema.parse(JSON.parse(file));
|
|
694
|
+
return license;
|
|
695
|
+
} catch (err) {
|
|
696
|
+
throw new MoonbaseError("File error", "Could not load local license", "LicenseInvalid" /* LicenseInvalid */, err);
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
async storeLocalLicense(license) {
|
|
700
|
+
await import_promises.default.writeFile(this.path, JSON.stringify(license), { encoding: "utf-8" });
|
|
701
|
+
}
|
|
702
|
+
async deleteLocalLicense() {
|
|
703
|
+
if (!import_node_fs2.default.existsSync(this.path))
|
|
704
|
+
return;
|
|
705
|
+
await import_promises.default.rm(this.path);
|
|
706
|
+
}
|
|
707
|
+
get path() {
|
|
708
|
+
var _a, _b, _c, _d;
|
|
709
|
+
return import_node_path.default.resolve((_b = (_a = this.options) == null ? void 0 : _a.dir) != null ? _b : import_node_path.default.resolve(), (_d = (_c = this.options) == null ? void 0 : _c.licenseFileName) != null ? _d : "license.mb");
|
|
710
|
+
}
|
|
711
|
+
};
|
|
712
|
+
|
|
713
|
+
// src/validator.ts
|
|
714
|
+
var import_jsonwebtoken = __toESM(require("jsonwebtoken"), 1);
|
|
715
|
+
var import_zod2 = require("zod");
|
|
716
|
+
var licenseClaimsSchema = import_zod2.z.object({
|
|
717
|
+
["l:id" /* LicenseId */]: import_zod2.z.string(),
|
|
718
|
+
["trial" /* Trial */]: import_zod2.z.string().or(import_zod2.z.boolean()).transform((v) => v === true || v === "true").pipe(import_zod2.z.boolean()),
|
|
719
|
+
["method" /* ActivationMethod */]: import_zod2.z.nativeEnum(ActivationMethod),
|
|
720
|
+
["sig" /* ComputerSignature */]: import_zod2.z.string(),
|
|
721
|
+
["iat" /* IssuedAt */]: import_zod2.z.number().transform((v) => new Date(v * 1e3)).pipe(import_zod2.z.date()),
|
|
722
|
+
["exp" /* ExpiresAt */]: import_zod2.z.number().nullish().transform((v) => v ? new Date(v * 1e3) : void 0).pipe(import_zod2.z.date().nullish()),
|
|
723
|
+
["validated" /* ValidatedAt */]: import_zod2.z.number().transform((v) => new Date(v * 1e3)).pipe(import_zod2.z.date()),
|
|
724
|
+
["p:id" /* ProductId */]: import_zod2.z.string(),
|
|
725
|
+
["p:name" /* ProductName */]: import_zod2.z.string(),
|
|
726
|
+
["p:rel" /* ProductReleaseVersion */]: import_zod2.z.string().nullish(),
|
|
727
|
+
["sp:owned" /* OwnedSubProducts */]: import_zod2.z.string().nullish().transform((v) => v ? v.split(",") : []),
|
|
728
|
+
["s:id" /* SubscriptionId */]: import_zod2.z.string().nullish(),
|
|
729
|
+
["u:id" /* UserId */]: import_zod2.z.string(),
|
|
730
|
+
["u:name" /* UserName */]: import_zod2.z.string(),
|
|
731
|
+
["u:email" /* UserEmail */]: import_zod2.z.string(),
|
|
732
|
+
["p:properties" /* ProductProperties */]: import_zod2.z.record(import_zod2.z.unknown()).nullish(),
|
|
733
|
+
["u:properties" /* UserProperties */]: import_zod2.z.record(import_zod2.z.unknown()).nullish(),
|
|
734
|
+
["l:properties" /* LicenseProperties */]: import_zod2.z.record(import_zod2.z.unknown()).nullish(),
|
|
735
|
+
["t:properties" /* TrialProperties */]: import_zod2.z.record(import_zod2.z.unknown()).nullish()
|
|
736
|
+
});
|
|
737
|
+
var LicenseValidator = class {
|
|
738
|
+
constructor(configuration, deviceIdResolver) {
|
|
739
|
+
this.configuration = configuration;
|
|
740
|
+
this.deviceIdResolver = deviceIdResolver;
|
|
741
|
+
}
|
|
742
|
+
async validateLicense(token) {
|
|
743
|
+
const [license, claims] = await this.parseLicenseToken(token);
|
|
744
|
+
if (license.expiresAt && license.expiresAt < /* @__PURE__ */ new Date()) {
|
|
745
|
+
throw new MoonbaseError(
|
|
746
|
+
"License expired",
|
|
747
|
+
"This license has expired",
|
|
748
|
+
"LicenseExpired" /* LicenseExpired */
|
|
749
|
+
);
|
|
750
|
+
}
|
|
751
|
+
const expectedSignature = await this.deviceIdResolver.resolveDeviceId();
|
|
752
|
+
const boundSignature = claims["sig" /* ComputerSignature */];
|
|
753
|
+
if (expectedSignature !== boundSignature && !await this.acceptsHistoricalDeviceId(boundSignature))
|
|
754
|
+
throw deviceMismatchError(expectedSignature, boundSignature);
|
|
755
|
+
return license;
|
|
756
|
+
}
|
|
757
|
+
/**
|
|
758
|
+
* Give a {@link IMigratingDeviceIdResolver} the chance to vouch for a device id
|
|
759
|
+
* this machine used to have. Only consulted after the fast path fails, so
|
|
760
|
+
* apps that have not opted into a migration pay nothing.
|
|
761
|
+
*/
|
|
762
|
+
async acceptsHistoricalDeviceId(boundSignature) {
|
|
763
|
+
const accepts = this.deviceIdResolver.acceptsDeviceId;
|
|
764
|
+
return typeof accepts === "function" && await accepts.call(this.deviceIdResolver, boundSignature);
|
|
765
|
+
}
|
|
766
|
+
parseLicenseToken(token) {
|
|
767
|
+
return new Promise((resolve, reject) => {
|
|
768
|
+
import_jsonwebtoken.default.verify(token, this.configuration.publicKey, {
|
|
769
|
+
ignoreExpiration: true,
|
|
770
|
+
issuer: this.configuration.accountId,
|
|
771
|
+
audience: this.configuration.productId
|
|
772
|
+
}, (err, decoded) => {
|
|
773
|
+
var _a, _b, _c, _d, _e;
|
|
774
|
+
if (err) {
|
|
775
|
+
reject(new MoonbaseError(
|
|
776
|
+
"Could not validate license",
|
|
777
|
+
err.message,
|
|
778
|
+
"LicenseInvalid" /* LicenseInvalid */,
|
|
779
|
+
err
|
|
780
|
+
));
|
|
781
|
+
return;
|
|
782
|
+
}
|
|
783
|
+
if (typeof decoded === "string") {
|
|
784
|
+
reject(new MoonbaseError(
|
|
785
|
+
"Could not validate license",
|
|
786
|
+
"The given license token could not be parsed",
|
|
787
|
+
"LicenseInvalid" /* LicenseInvalid */
|
|
788
|
+
));
|
|
789
|
+
return;
|
|
790
|
+
}
|
|
791
|
+
try {
|
|
792
|
+
const claims = licenseClaimsSchema.parse(decoded);
|
|
793
|
+
resolve([{
|
|
794
|
+
id: claims["l:id" /* LicenseId */],
|
|
795
|
+
trial: claims["trial" /* Trial */],
|
|
796
|
+
activationMethod: claims["method" /* ActivationMethod */],
|
|
797
|
+
product: {
|
|
798
|
+
id: claims["p:id" /* ProductId */],
|
|
799
|
+
name: claims["p:name" /* ProductName */],
|
|
800
|
+
currentReleaseVersion: (_a = claims["p:rel" /* ProductReleaseVersion */]) != null ? _a : void 0,
|
|
801
|
+
properties: (_b = claims["p:properties" /* ProductProperties */]) != null ? _b : void 0
|
|
802
|
+
},
|
|
803
|
+
ownedSubProductIds: claims["sp:owned" /* OwnedSubProducts */],
|
|
804
|
+
subscriptionId: (_c = claims["s:id" /* SubscriptionId */]) != null ? _c : void 0,
|
|
805
|
+
issuedTo: {
|
|
806
|
+
id: claims["u:id" /* UserId */],
|
|
807
|
+
name: claims["u:name" /* UserName */],
|
|
808
|
+
email: claims["u:email" /* UserEmail */],
|
|
809
|
+
properties: (_d = claims["u:properties" /* UserProperties */]) != null ? _d : void 0
|
|
810
|
+
},
|
|
811
|
+
expiresAt: claims["exp" /* ExpiresAt */] || void 0,
|
|
812
|
+
issuedAt: claims["iat" /* IssuedAt */],
|
|
813
|
+
validatedAt: claims["validated" /* ValidatedAt */],
|
|
814
|
+
properties: (_e = claims["trial" /* Trial */] ? claims["t:properties" /* TrialProperties */] : claims["l:properties" /* LicenseProperties */]) != null ? _e : void 0,
|
|
815
|
+
token
|
|
816
|
+
}, claims]);
|
|
817
|
+
} catch (err2) {
|
|
818
|
+
const error = err2;
|
|
819
|
+
reject(new MoonbaseError(
|
|
820
|
+
"Could not validate license",
|
|
821
|
+
error.message,
|
|
822
|
+
"LicenseInvalid" /* LicenseInvalid */,
|
|
823
|
+
error
|
|
824
|
+
));
|
|
825
|
+
}
|
|
826
|
+
});
|
|
827
|
+
});
|
|
828
|
+
}
|
|
829
|
+
};
|
|
830
|
+
function deviceMismatchError(expected, bound) {
|
|
831
|
+
const detail = "This license is not for this device";
|
|
832
|
+
const versionNote = describeVersionDifference(expected, bound);
|
|
833
|
+
return new MoonbaseError(
|
|
834
|
+
"License is for another device",
|
|
835
|
+
versionNote ? `${detail}. ${versionNote}` : detail,
|
|
836
|
+
"LicenseDeviceMismatch" /* LicenseDeviceMismatch */
|
|
837
|
+
);
|
|
838
|
+
}
|
|
839
|
+
function describeVersionDifference(expected, bound) {
|
|
840
|
+
const expectedStamp = parseDeviceIdStamp(expected);
|
|
841
|
+
if (!expectedStamp)
|
|
842
|
+
return null;
|
|
843
|
+
const boundStamp = parseDeviceIdStamp(bound);
|
|
844
|
+
if (boundStamp && boundStamp.version === expectedStamp.version)
|
|
845
|
+
return null;
|
|
846
|
+
if (boundStamp && boundStamp.version > expectedStamp.version) {
|
|
847
|
+
return `The binding was created by device fingerprint v${boundStamp.version}, which is newer than the v${expectedStamp.version} this SDK computes \u2014 update the SDK rather than re-activating, which would rebind the device to the older algorithm.`;
|
|
848
|
+
}
|
|
849
|
+
const boundVersion = boundStamp ? `device fingerprint v${boundStamp.version}` : "an SDK predating versioned device fingerprints";
|
|
850
|
+
return `The binding was created by ${boundVersion}, while this SDK computes v${expectedStamp.version}, so this may instead be the same machine bound under the older algorithm \u2014 re-activate to find out, or configure a MigratingDeviceIdResolver to keep accepting the previous id.`;
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
// src/index.ts
|
|
854
|
+
function detectPlatform() {
|
|
855
|
+
if (typeof import_node_process3.default === "undefined")
|
|
856
|
+
return void 0;
|
|
857
|
+
switch (import_node_process3.default.platform) {
|
|
858
|
+
case "darwin":
|
|
859
|
+
return "Mac";
|
|
860
|
+
case "win32":
|
|
861
|
+
return "Windows";
|
|
862
|
+
case "linux":
|
|
863
|
+
return "Linux";
|
|
864
|
+
default:
|
|
865
|
+
return void 0;
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
var MoonbaseLicensing = class {
|
|
869
|
+
constructor(configuration) {
|
|
870
|
+
var _a, _b;
|
|
871
|
+
this.configuration = {
|
|
872
|
+
...configuration,
|
|
873
|
+
endpoint: configuration.endpoint.replace(/\/$/, ""),
|
|
874
|
+
platform: configuration.platform === void 0 ? detectPlatform() : configuration.platform
|
|
875
|
+
};
|
|
876
|
+
this.store = (_a = configuration.licenseStore) != null ? _a : new InMemoryLicenseStore();
|
|
877
|
+
this.deviceIdResolver = (_b = configuration.deviceIdResolver) != null ? _b : new MoonbaseDeviceIdResolver();
|
|
878
|
+
this.validator = new LicenseValidator(this.configuration, this.deviceIdResolver);
|
|
879
|
+
this.client = new LicenseClient(this.configuration, this.deviceIdResolver, this.validator);
|
|
880
|
+
}
|
|
881
|
+
async generateDeviceToken() {
|
|
882
|
+
const token = {
|
|
883
|
+
id: await this.deviceIdResolver.resolveDeviceId(),
|
|
884
|
+
name: await this.deviceIdResolver.resolveDeviceName(),
|
|
885
|
+
productId: this.configuration.productId,
|
|
886
|
+
format: "JWT"
|
|
887
|
+
};
|
|
888
|
+
const json = JSON.stringify(token);
|
|
889
|
+
return import_node_buffer2.Buffer.from(import_node_buffer2.Buffer.from(json).toString("base64"));
|
|
890
|
+
}
|
|
891
|
+
async readRawLicense(license) {
|
|
892
|
+
return await this.client.validateRawLicense(license);
|
|
893
|
+
}
|
|
894
|
+
};
|
|
895
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
896
|
+
0 && (module.exports = {
|
|
897
|
+
ActivationMethod,
|
|
898
|
+
ErrorType,
|
|
899
|
+
FINGERPRINT_PREFIX,
|
|
900
|
+
FINGERPRINT_VERSION,
|
|
901
|
+
FileLicenseStore,
|
|
902
|
+
IDENTIFYING_PARAM_NAMES,
|
|
903
|
+
InMemoryLicenseStore,
|
|
904
|
+
InsufficientDeviceIdentityError,
|
|
905
|
+
LegacyDeviceIdResolver,
|
|
906
|
+
LicenseClient,
|
|
907
|
+
LicenseValidator,
|
|
908
|
+
MAX_VALUE_LENGTH,
|
|
909
|
+
MigratingDeviceIdResolver,
|
|
910
|
+
MoonbaseDeviceIdResolver,
|
|
911
|
+
MoonbaseError,
|
|
912
|
+
MoonbaseLicensing,
|
|
913
|
+
buildFingerprintMaterial,
|
|
914
|
+
canonicalizeParams,
|
|
915
|
+
canonicalizeValue,
|
|
916
|
+
defaultDeviceIdentityReader,
|
|
917
|
+
fingerprintDeviceId,
|
|
918
|
+
fingerprintDigest,
|
|
919
|
+
parseDeviceIdStamp,
|
|
920
|
+
parseIoregPlatformUuid,
|
|
921
|
+
parseSmbiosParams,
|
|
922
|
+
platformTag,
|
|
923
|
+
selectMachineId,
|
|
924
|
+
stampDeviceId
|
|
925
|
+
});
|