@mui/x-license 7.16.0 → 7.17.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 +87 -0
- package/generateLicense/generateLicense.d.ts +12 -6
- package/generateLicense/generateLicense.js +4 -4
- package/index.js +1 -1
- package/modern/generateLicense/generateLicense.js +4 -4
- package/modern/index.js +1 -1
- package/{utils/licensingModel.js → modern/utils/licenseModel.js} +2 -2
- package/modern/utils/plan.js +2 -0
- package/modern/verifyLicense/verifyLicense.js +18 -18
- package/node/generateLicense/generateLicense.js +4 -4
- package/node/index.js +1 -1
- package/node/utils/{licensingModel.js → licenseModel.js} +3 -3
- package/node/utils/{licenseScope.js → plan.js} +2 -2
- package/node/verifyLicense/verifyLicense.js +18 -18
- package/package.json +1 -1
- package/utils/index.d.ts +2 -2
- package/utils/licenseModel.d.ts +2 -0
- package/{modern/utils/licensingModel.js → utils/licenseModel.js} +2 -2
- package/utils/{licenseScope.d.ts → plan.d.ts} +2 -2
- package/utils/plan.js +2 -0
- package/verifyLicense/verifyLicense.js +18 -18
- package/modern/utils/licenseScope.js +0 -2
- package/utils/licenseScope.js +0 -2
- package/utils/licensingModel.d.ts +0 -2
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,93 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## 7.17.0
|
|
7
|
+
|
|
8
|
+
_Sep 13, 2024_
|
|
9
|
+
|
|
10
|
+
We'd like to offer a big thanks to the 12 contributors who made this release possible. Here are some highlights ✨:
|
|
11
|
+
|
|
12
|
+
- 📊 Charts performance improvement
|
|
13
|
+
- 🧑💻 New Data Grid [custom columns demo](https://mui.com/x/react-data-grid/custom-columns/#full-example)
|
|
14
|
+
- 🐞 Bugfixes
|
|
15
|
+
- 📚 Documentation improvements
|
|
16
|
+
- 🌍 Improve Hungarian (hu-HU) locale on the Data Grid
|
|
17
|
+
|
|
18
|
+
<!--/ HIGHLIGHT_ABOVE_SEPARATOR /-->
|
|
19
|
+
|
|
20
|
+
### Data Grid
|
|
21
|
+
|
|
22
|
+
#### `@mui/x-data-grid@7.17.0`
|
|
23
|
+
|
|
24
|
+
- [DataGrid] Add "does not equal" and "does not contain" filter operators (#14489) @KenanYusuf
|
|
25
|
+
- [DataGrid] Add demo to the "Custom columns" page that does not use generator (#13695) @arminmeh
|
|
26
|
+
- [DataGrid] Fix Voice Over reading the column name twice (#14482) @arminmeh
|
|
27
|
+
- [DataGrid] Fix bug in CRUD example (#14513) @michelengelen
|
|
28
|
+
- [DataGrid] Fix failing jsdom tests caused by `:has()` selectors (#14559) @KenanYusuf
|
|
29
|
+
- [DataGrid] Refactor string operator filter functions (#14564) @KenanYusuf
|
|
30
|
+
- [l10n] Improve Hungarian (hu-HU) locale (#14506) @ntamas
|
|
31
|
+
|
|
32
|
+
#### `@mui/x-data-grid-pro@7.17.0` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
33
|
+
|
|
34
|
+
Same changes as in `@mui/x-data-grid@7.17.0`.
|
|
35
|
+
|
|
36
|
+
#### `@mui/x-data-grid-premium@7.17.0` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
37
|
+
|
|
38
|
+
Same changes as in `@mui/x-data-grid-pro@7.17.0`.
|
|
39
|
+
|
|
40
|
+
### Date and Time Pickers
|
|
41
|
+
|
|
42
|
+
#### `@mui/x-date-pickers@7.17.0`
|
|
43
|
+
|
|
44
|
+
- [fields] Improve `useSplitFieldProps` and make it public (#14514) @flaviendelangle
|
|
45
|
+
- [pickers] Improve clear action label (#14243) @oliviertassinari
|
|
46
|
+
- [pickers] Add `"use client"` directive to every public component and hook (#14562) @flaviendelangle
|
|
47
|
+
- [pickers] Allow custom fields to validate the value (#14486) @flaviendelangle
|
|
48
|
+
- [pickers] Stop using utils in locales (#14505) @flaviendelangle
|
|
49
|
+
|
|
50
|
+
#### `@mui/x-date-pickers-pro@7.17.0` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
51
|
+
|
|
52
|
+
Same changes as in `@mui/x-date-pickers@7.17.0`, plus:
|
|
53
|
+
|
|
54
|
+
- [DateRangePicker] Fix `currentMonthCalendarPosition` not scrolling to future sibling (#14442) @GMchris
|
|
55
|
+
|
|
56
|
+
### Charts
|
|
57
|
+
|
|
58
|
+
#### `@mui/x-charts@7.17.0`
|
|
59
|
+
|
|
60
|
+
- [charts] Add `"use client"` directive to every public component and hook (#14578) @flaviendelangle
|
|
61
|
+
- [charts] Allow `onItemClick` on the `Legend` component (#14231) @JCQuintas
|
|
62
|
+
- [charts] Fix `onAxisClick` with `layout='horizontal'` (#14547) @alexfauquette
|
|
63
|
+
- [charts] Replace `path` with `circle` for performance improvement (#14518) @alexfauquette
|
|
64
|
+
|
|
65
|
+
#### `@mui/x-charts-pro@7.0.0-beta.1` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
66
|
+
|
|
67
|
+
Same changes as in `@mui/x-charts@7.17.0`.
|
|
68
|
+
|
|
69
|
+
### Tree View
|
|
70
|
+
|
|
71
|
+
#### `@mui/x-tree-view@7.17.0`
|
|
72
|
+
|
|
73
|
+
- [TreeView] Make `useTreeItem2` stable (#14498) @flaviendelangle
|
|
74
|
+
|
|
75
|
+
### Docs
|
|
76
|
+
|
|
77
|
+
- [docs] Add missing callout on "Imperative API" tree view sections (#14503) @flaviendelangle
|
|
78
|
+
- [docs] Fix broken redirection to MUI X v5 @oliviertassinari
|
|
79
|
+
- [docs] Fix multiple `console.error` messages on `charts` docs (#14554) @JCQuintas
|
|
80
|
+
- [docs] Fixed typo in Row Grouping recipes (#14549) @Miodini
|
|
81
|
+
- [docs] Match title with blog posts @oliviertassinari
|
|
82
|
+
|
|
83
|
+
### Core
|
|
84
|
+
|
|
85
|
+
- [core] Move warning methods to `@mui/x-internals` (#14528) @k-rajat19
|
|
86
|
+
- [core] Sync with core release flow @oliviertassinari
|
|
87
|
+
- [code-infra] Fix charts benchmark workflow (#14573) @JCQuintas
|
|
88
|
+
- [docs-infra] Type interface API pages (#14138) @alexfauquette
|
|
89
|
+
- [infra] Create `ESLint plugins` renovate group (#14574) @LukasTy
|
|
90
|
+
- [license] Clean-up terminology to match codebase (#14531) @oliviertassinari
|
|
91
|
+
- [test] Remove dead `act()` logic (#14529) @oliviertassinari
|
|
92
|
+
|
|
6
93
|
## 7.16.0
|
|
7
94
|
|
|
8
95
|
_Sep 5, 2024_
|
|
@@ -1,12 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { PlanScope, PlanVersion } from '../utils/plan';
|
|
2
|
+
import { LicenseModel } from '../utils/licenseModel';
|
|
3
3
|
export interface LicenseDetails {
|
|
4
4
|
orderNumber: string;
|
|
5
5
|
expiryDate: Date;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
/**
|
|
7
|
+
* @deprecated Use planScope instead.
|
|
8
|
+
*/
|
|
9
|
+
scope?: PlanScope;
|
|
10
|
+
planScope?: PlanScope;
|
|
11
|
+
/**
|
|
12
|
+
* @deprecated Use licenseModel instead.
|
|
13
|
+
*/
|
|
14
|
+
licensingModel?: LicenseModel;
|
|
15
|
+
licenseModel?: LicenseModel;
|
|
10
16
|
planVersion: PlanVersion;
|
|
11
17
|
}
|
|
12
18
|
export declare function generateLicense(details: LicenseDetails): string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { md5 } from "../encoding/md5.js";
|
|
2
2
|
import { base64Encode } from "../encoding/base64.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { PLAN_SCOPES } from "../utils/plan.js";
|
|
4
|
+
import { LICENSE_MODELS } from "../utils/licenseModel.js";
|
|
5
5
|
const licenseVersion = '2';
|
|
6
6
|
function getClearLicenseString(details) {
|
|
7
7
|
// TODO remove
|
|
@@ -12,10 +12,10 @@ function getClearLicenseString(details) {
|
|
|
12
12
|
if (details.scope) {
|
|
13
13
|
details.planScope = details.scope;
|
|
14
14
|
}
|
|
15
|
-
if (details.planScope && !
|
|
15
|
+
if (details.planScope && !PLAN_SCOPES.includes(details.planScope)) {
|
|
16
16
|
throw new Error('MUI X: Invalid scope');
|
|
17
17
|
}
|
|
18
|
-
if (details.licenseModel && !
|
|
18
|
+
if (details.licenseModel && !LICENSE_MODELS.includes(details.licenseModel)) {
|
|
19
19
|
throw new Error('MUI X: Invalid licensing model');
|
|
20
20
|
}
|
|
21
21
|
const keyParts = [`O=${details.orderNumber}`, `E=${details.expiryDate.getTime()}`, `S=${details.planScope}`, `LM=${details.licenseModel}`, `PV=${details.planVersion}`, `KV=${licenseVersion}`];
|
package/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { md5 } from "../encoding/md5.js";
|
|
2
2
|
import { base64Encode } from "../encoding/base64.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { PLAN_SCOPES } from "../utils/plan.js";
|
|
4
|
+
import { LICENSE_MODELS } from "../utils/licenseModel.js";
|
|
5
5
|
const licenseVersion = '2';
|
|
6
6
|
function getClearLicenseString(details) {
|
|
7
7
|
// TODO remove
|
|
@@ -12,10 +12,10 @@ function getClearLicenseString(details) {
|
|
|
12
12
|
if (details.scope) {
|
|
13
13
|
details.planScope = details.scope;
|
|
14
14
|
}
|
|
15
|
-
if (details.planScope && !
|
|
15
|
+
if (details.planScope && !PLAN_SCOPES.includes(details.planScope)) {
|
|
16
16
|
throw new Error('MUI X: Invalid scope');
|
|
17
17
|
}
|
|
18
|
-
if (details.licenseModel && !
|
|
18
|
+
if (details.licenseModel && !LICENSE_MODELS.includes(details.licenseModel)) {
|
|
19
19
|
throw new Error('MUI X: Invalid licensing model');
|
|
20
20
|
}
|
|
21
21
|
const keyParts = [`O=${details.orderNumber}`, `E=${details.expiryDate.getTime()}`, `S=${details.planScope}`, `LM=${details.licenseModel}`, `PV=${details.planVersion}`, `KV=${licenseVersion}`];
|
package/modern/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const
|
|
1
|
+
export const LICENSE_MODELS = [
|
|
2
2
|
/**
|
|
3
3
|
* A license is outdated if the current version of the software was released after the expiry date of the license.
|
|
4
4
|
* But the license can be used indefinitely with an older version of the software.
|
|
@@ -10,6 +10,6 @@ export const LICENSING_MODELS = [
|
|
|
10
10
|
*/
|
|
11
11
|
'annual',
|
|
12
12
|
/**
|
|
13
|
-
* TODO
|
|
13
|
+
* TODO 2026 remove, legacy name of annual.
|
|
14
14
|
*/
|
|
15
15
|
'subscription'];
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { base64Decode, base64Encode } from "../encoding/base64.js";
|
|
2
2
|
import { md5 } from "../encoding/md5.js";
|
|
3
3
|
import { LICENSE_STATUS } from "../utils/licenseStatus.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { PLAN_SCOPES } from "../utils/plan.js";
|
|
5
|
+
import { LICENSE_MODELS } from "../utils/licenseModel.js";
|
|
6
6
|
const getDefaultReleaseDate = () => {
|
|
7
7
|
const today = new Date();
|
|
8
8
|
today.setHours(0, 0, 0, 0);
|
|
@@ -11,7 +11,7 @@ const getDefaultReleaseDate = () => {
|
|
|
11
11
|
export function generateReleaseInfo(releaseDate = getDefaultReleaseDate()) {
|
|
12
12
|
return base64Encode(releaseDate.getTime().toString());
|
|
13
13
|
}
|
|
14
|
-
function
|
|
14
|
+
function isPlanScopeSufficient(packageName, planScope) {
|
|
15
15
|
let acceptedScopes;
|
|
16
16
|
if (packageName.includes('-pro')) {
|
|
17
17
|
acceptedScopes = ['pro', 'premium'];
|
|
@@ -20,7 +20,7 @@ function isLicenseScopeSufficient(packageName, licenseScope) {
|
|
|
20
20
|
} else {
|
|
21
21
|
acceptedScopes = [];
|
|
22
22
|
}
|
|
23
|
-
return acceptedScopes.includes(
|
|
23
|
+
return acceptedScopes.includes(planScope);
|
|
24
24
|
}
|
|
25
25
|
const expiryReg = /^.*EXPIRY=([0-9]+),.*$/;
|
|
26
26
|
const PRO_PACKAGES_AVAILABLE_IN_INITIAL_PRO_PLAN = ['x-data-grid-pro', 'x-date-pickers-pro'];
|
|
@@ -39,29 +39,29 @@ const decodeLicenseVersion1 = license => {
|
|
|
39
39
|
expiryTimestamp = null;
|
|
40
40
|
}
|
|
41
41
|
return {
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
planScope: 'pro',
|
|
43
|
+
licenseModel: 'perpetual',
|
|
44
44
|
expiryTimestamp,
|
|
45
45
|
planVersion: 'initial'
|
|
46
46
|
};
|
|
47
47
|
};
|
|
48
48
|
|
|
49
49
|
/**
|
|
50
|
-
* Format: O=${orderNumber},E=${expiryTimestamp},S=${
|
|
50
|
+
* Format: O=${orderNumber},E=${expiryTimestamp},S=${planScope},LM=${licenseModel},PV=${planVersion},KV=2`;
|
|
51
51
|
*/
|
|
52
52
|
const decodeLicenseVersion2 = license => {
|
|
53
53
|
const licenseInfo = {
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
planScope: null,
|
|
55
|
+
licenseModel: null,
|
|
56
56
|
expiryTimestamp: null,
|
|
57
57
|
planVersion: 'initial'
|
|
58
58
|
};
|
|
59
59
|
license.split(',').map(token => token.split('=')).filter(el => el.length === 2).forEach(([key, value]) => {
|
|
60
60
|
if (key === 'S') {
|
|
61
|
-
licenseInfo.
|
|
61
|
+
licenseInfo.planScope = value;
|
|
62
62
|
}
|
|
63
63
|
if (key === 'LM') {
|
|
64
|
-
licenseInfo.
|
|
64
|
+
licenseInfo.licenseModel = value;
|
|
65
65
|
}
|
|
66
66
|
if (key === 'E') {
|
|
67
67
|
const expiryTimestamp = parseInt(value, 10);
|
|
@@ -116,7 +116,7 @@ export function verifyLicense({
|
|
|
116
116
|
status: LICENSE_STATUS.Invalid
|
|
117
117
|
};
|
|
118
118
|
}
|
|
119
|
-
if (license.
|
|
119
|
+
if (license.licenseModel == null || !LICENSE_MODELS.includes(license.licenseModel)) {
|
|
120
120
|
console.error('MUI X: Error checking license. Licensing model not found or invalid!');
|
|
121
121
|
return {
|
|
122
122
|
status: LICENSE_STATUS.Invalid
|
|
@@ -128,7 +128,7 @@ export function verifyLicense({
|
|
|
128
128
|
status: LICENSE_STATUS.Invalid
|
|
129
129
|
};
|
|
130
130
|
}
|
|
131
|
-
if (license.
|
|
131
|
+
if (license.licenseModel === 'perpetual' || process.env.NODE_ENV === 'production') {
|
|
132
132
|
const pkgTimestamp = parseInt(base64Decode(releaseInfo), 10);
|
|
133
133
|
if (Number.isNaN(pkgTimestamp)) {
|
|
134
134
|
throw new Error('MUI X: The release information is invalid. Not able to validate license.');
|
|
@@ -138,7 +138,7 @@ export function verifyLicense({
|
|
|
138
138
|
status: LICENSE_STATUS.ExpiredVersion
|
|
139
139
|
};
|
|
140
140
|
}
|
|
141
|
-
} else if (license.
|
|
141
|
+
} else if (license.licenseModel === 'subscription' || license.licenseModel === 'annual') {
|
|
142
142
|
if (new Date().getTime() > license.expiryTimestamp) {
|
|
143
143
|
if (
|
|
144
144
|
// 30 days grace
|
|
@@ -160,20 +160,20 @@ export function verifyLicense({
|
|
|
160
160
|
};
|
|
161
161
|
}
|
|
162
162
|
}
|
|
163
|
-
if (license.
|
|
164
|
-
console.error('MUI X: Error checking license.
|
|
163
|
+
if (license.planScope == null || !PLAN_SCOPES.includes(license.planScope)) {
|
|
164
|
+
console.error('MUI X: Error checking license. planScope not found or invalid!');
|
|
165
165
|
return {
|
|
166
166
|
status: LICENSE_STATUS.Invalid
|
|
167
167
|
};
|
|
168
168
|
}
|
|
169
|
-
if (!
|
|
169
|
+
if (!isPlanScopeSufficient(packageName, license.planScope)) {
|
|
170
170
|
return {
|
|
171
171
|
status: LICENSE_STATUS.OutOfScope
|
|
172
172
|
};
|
|
173
173
|
}
|
|
174
174
|
|
|
175
175
|
// 'charts-pro' or 'tree-view-pro' can only be used with a newer Pro license
|
|
176
|
-
if (license.planVersion === 'initial' && license.
|
|
176
|
+
if (license.planVersion === 'initial' && license.planScope === 'pro' && !PRO_PACKAGES_AVAILABLE_IN_INITIAL_PRO_PLAN.includes(packageName)) {
|
|
177
177
|
return {
|
|
178
178
|
status: LICENSE_STATUS.NotAvailableInInitialProPlan
|
|
179
179
|
};
|
|
@@ -6,8 +6,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.generateLicense = generateLicense;
|
|
7
7
|
var _md = require("../encoding/md5");
|
|
8
8
|
var _base = require("../encoding/base64");
|
|
9
|
-
var
|
|
10
|
-
var
|
|
9
|
+
var _plan = require("../utils/plan");
|
|
10
|
+
var _licenseModel = require("../utils/licenseModel");
|
|
11
11
|
const licenseVersion = '2';
|
|
12
12
|
function getClearLicenseString(details) {
|
|
13
13
|
// TODO remove
|
|
@@ -18,10 +18,10 @@ function getClearLicenseString(details) {
|
|
|
18
18
|
if (details.scope) {
|
|
19
19
|
details.planScope = details.scope;
|
|
20
20
|
}
|
|
21
|
-
if (details.planScope && !
|
|
21
|
+
if (details.planScope && !_plan.PLAN_SCOPES.includes(details.planScope)) {
|
|
22
22
|
throw new Error('MUI X: Invalid scope');
|
|
23
23
|
}
|
|
24
|
-
if (details.licenseModel && !
|
|
24
|
+
if (details.licenseModel && !_licenseModel.LICENSE_MODELS.includes(details.licenseModel)) {
|
|
25
25
|
throw new Error('MUI X: Invalid licensing model');
|
|
26
26
|
}
|
|
27
27
|
const keyParts = [`O=${details.orderNumber}`, `E=${details.expiryDate.getTime()}`, `S=${details.planScope}`, `LM=${details.licenseModel}`, `PV=${details.planVersion}`, `KV=${licenseVersion}`];
|
package/node/index.js
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
7
|
-
const
|
|
6
|
+
exports.LICENSE_MODELS = void 0;
|
|
7
|
+
const LICENSE_MODELS = exports.LICENSE_MODELS = [
|
|
8
8
|
/**
|
|
9
9
|
* A license is outdated if the current version of the software was released after the expiry date of the license.
|
|
10
10
|
* But the license can be used indefinitely with an older version of the software.
|
|
@@ -16,6 +16,6 @@ const LICENSING_MODELS = exports.LICENSING_MODELS = [
|
|
|
16
16
|
*/
|
|
17
17
|
'annual',
|
|
18
18
|
/**
|
|
19
|
-
* TODO
|
|
19
|
+
* TODO 2026 remove, legacy name of annual.
|
|
20
20
|
*/
|
|
21
21
|
'subscription'];
|
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.PLAN_VERSIONS = exports.
|
|
7
|
-
const
|
|
6
|
+
exports.PLAN_VERSIONS = exports.PLAN_SCOPES = void 0;
|
|
7
|
+
const PLAN_SCOPES = exports.PLAN_SCOPES = ['pro', 'premium'];
|
|
8
8
|
const PLAN_VERSIONS = exports.PLAN_VERSIONS = ['initial', 'Q3-2024'];
|
|
@@ -8,8 +8,8 @@ exports.verifyLicense = verifyLicense;
|
|
|
8
8
|
var _base = require("../encoding/base64");
|
|
9
9
|
var _md = require("../encoding/md5");
|
|
10
10
|
var _licenseStatus = require("../utils/licenseStatus");
|
|
11
|
-
var
|
|
12
|
-
var
|
|
11
|
+
var _plan = require("../utils/plan");
|
|
12
|
+
var _licenseModel = require("../utils/licenseModel");
|
|
13
13
|
const getDefaultReleaseDate = () => {
|
|
14
14
|
const today = new Date();
|
|
15
15
|
today.setHours(0, 0, 0, 0);
|
|
@@ -18,7 +18,7 @@ const getDefaultReleaseDate = () => {
|
|
|
18
18
|
function generateReleaseInfo(releaseDate = getDefaultReleaseDate()) {
|
|
19
19
|
return (0, _base.base64Encode)(releaseDate.getTime().toString());
|
|
20
20
|
}
|
|
21
|
-
function
|
|
21
|
+
function isPlanScopeSufficient(packageName, planScope) {
|
|
22
22
|
let acceptedScopes;
|
|
23
23
|
if (packageName.includes('-pro')) {
|
|
24
24
|
acceptedScopes = ['pro', 'premium'];
|
|
@@ -27,7 +27,7 @@ function isLicenseScopeSufficient(packageName, licenseScope) {
|
|
|
27
27
|
} else {
|
|
28
28
|
acceptedScopes = [];
|
|
29
29
|
}
|
|
30
|
-
return acceptedScopes.includes(
|
|
30
|
+
return acceptedScopes.includes(planScope);
|
|
31
31
|
}
|
|
32
32
|
const expiryReg = /^.*EXPIRY=([0-9]+),.*$/;
|
|
33
33
|
const PRO_PACKAGES_AVAILABLE_IN_INITIAL_PRO_PLAN = ['x-data-grid-pro', 'x-date-pickers-pro'];
|
|
@@ -46,29 +46,29 @@ const decodeLicenseVersion1 = license => {
|
|
|
46
46
|
expiryTimestamp = null;
|
|
47
47
|
}
|
|
48
48
|
return {
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
planScope: 'pro',
|
|
50
|
+
licenseModel: 'perpetual',
|
|
51
51
|
expiryTimestamp,
|
|
52
52
|
planVersion: 'initial'
|
|
53
53
|
};
|
|
54
54
|
};
|
|
55
55
|
|
|
56
56
|
/**
|
|
57
|
-
* Format: O=${orderNumber},E=${expiryTimestamp},S=${
|
|
57
|
+
* Format: O=${orderNumber},E=${expiryTimestamp},S=${planScope},LM=${licenseModel},PV=${planVersion},KV=2`;
|
|
58
58
|
*/
|
|
59
59
|
const decodeLicenseVersion2 = license => {
|
|
60
60
|
const licenseInfo = {
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
planScope: null,
|
|
62
|
+
licenseModel: null,
|
|
63
63
|
expiryTimestamp: null,
|
|
64
64
|
planVersion: 'initial'
|
|
65
65
|
};
|
|
66
66
|
license.split(',').map(token => token.split('=')).filter(el => el.length === 2).forEach(([key, value]) => {
|
|
67
67
|
if (key === 'S') {
|
|
68
|
-
licenseInfo.
|
|
68
|
+
licenseInfo.planScope = value;
|
|
69
69
|
}
|
|
70
70
|
if (key === 'LM') {
|
|
71
|
-
licenseInfo.
|
|
71
|
+
licenseInfo.licenseModel = value;
|
|
72
72
|
}
|
|
73
73
|
if (key === 'E') {
|
|
74
74
|
const expiryTimestamp = parseInt(value, 10);
|
|
@@ -123,7 +123,7 @@ function verifyLicense({
|
|
|
123
123
|
status: _licenseStatus.LICENSE_STATUS.Invalid
|
|
124
124
|
};
|
|
125
125
|
}
|
|
126
|
-
if (license.
|
|
126
|
+
if (license.licenseModel == null || !_licenseModel.LICENSE_MODELS.includes(license.licenseModel)) {
|
|
127
127
|
console.error('MUI X: Error checking license. Licensing model not found or invalid!');
|
|
128
128
|
return {
|
|
129
129
|
status: _licenseStatus.LICENSE_STATUS.Invalid
|
|
@@ -135,7 +135,7 @@ function verifyLicense({
|
|
|
135
135
|
status: _licenseStatus.LICENSE_STATUS.Invalid
|
|
136
136
|
};
|
|
137
137
|
}
|
|
138
|
-
if (license.
|
|
138
|
+
if (license.licenseModel === 'perpetual' || process.env.NODE_ENV === 'production') {
|
|
139
139
|
const pkgTimestamp = parseInt((0, _base.base64Decode)(releaseInfo), 10);
|
|
140
140
|
if (Number.isNaN(pkgTimestamp)) {
|
|
141
141
|
throw new Error('MUI X: The release information is invalid. Not able to validate license.');
|
|
@@ -145,7 +145,7 @@ function verifyLicense({
|
|
|
145
145
|
status: _licenseStatus.LICENSE_STATUS.ExpiredVersion
|
|
146
146
|
};
|
|
147
147
|
}
|
|
148
|
-
} else if (license.
|
|
148
|
+
} else if (license.licenseModel === 'subscription' || license.licenseModel === 'annual') {
|
|
149
149
|
if (new Date().getTime() > license.expiryTimestamp) {
|
|
150
150
|
if (
|
|
151
151
|
// 30 days grace
|
|
@@ -167,20 +167,20 @@ function verifyLicense({
|
|
|
167
167
|
};
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
|
-
if (license.
|
|
171
|
-
console.error('MUI X: Error checking license.
|
|
170
|
+
if (license.planScope == null || !_plan.PLAN_SCOPES.includes(license.planScope)) {
|
|
171
|
+
console.error('MUI X: Error checking license. planScope not found or invalid!');
|
|
172
172
|
return {
|
|
173
173
|
status: _licenseStatus.LICENSE_STATUS.Invalid
|
|
174
174
|
};
|
|
175
175
|
}
|
|
176
|
-
if (!
|
|
176
|
+
if (!isPlanScopeSufficient(packageName, license.planScope)) {
|
|
177
177
|
return {
|
|
178
178
|
status: _licenseStatus.LICENSE_STATUS.OutOfScope
|
|
179
179
|
};
|
|
180
180
|
}
|
|
181
181
|
|
|
182
182
|
// 'charts-pro' or 'tree-view-pro' can only be used with a newer Pro license
|
|
183
|
-
if (license.planVersion === 'initial' && license.
|
|
183
|
+
if (license.planVersion === 'initial' && license.planScope === 'pro' && !PRO_PACKAGES_AVAILABLE_IN_INITIAL_PRO_PLAN.includes(packageName)) {
|
|
184
184
|
return {
|
|
185
185
|
status: _licenseStatus.LICENSE_STATUS.NotAvailableInInitialProPlan
|
|
186
186
|
};
|
package/package.json
CHANGED
package/utils/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from './licenseErrorMessageUtils';
|
|
2
2
|
export * from './licenseInfo';
|
|
3
3
|
export * from './licenseStatus';
|
|
4
|
-
export type {
|
|
5
|
-
export type {
|
|
4
|
+
export type { PlanScope } from './plan';
|
|
5
|
+
export type { LicenseModel } from './licenseModel';
|
|
6
6
|
export type { MuiCommercialPackageName } from './commercialPackages';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const
|
|
1
|
+
export const LICENSE_MODELS = [
|
|
2
2
|
/**
|
|
3
3
|
* A license is outdated if the current version of the software was released after the expiry date of the license.
|
|
4
4
|
* But the license can be used indefinitely with an older version of the software.
|
|
@@ -10,6 +10,6 @@ export const LICENSING_MODELS = [
|
|
|
10
10
|
*/
|
|
11
11
|
'annual',
|
|
12
12
|
/**
|
|
13
|
-
* TODO
|
|
13
|
+
* TODO 2026 remove, legacy name of annual.
|
|
14
14
|
*/
|
|
15
15
|
'subscription'];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const
|
|
1
|
+
export declare const PLAN_SCOPES: readonly ["pro", "premium"];
|
|
2
2
|
export declare const PLAN_VERSIONS: readonly ["initial", "Q3-2024"];
|
|
3
|
-
export type
|
|
3
|
+
export type PlanScope = (typeof PLAN_SCOPES)[number];
|
|
4
4
|
export type PlanVersion = (typeof PLAN_VERSIONS)[number];
|
package/utils/plan.js
ADDED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { base64Decode, base64Encode } from "../encoding/base64.js";
|
|
2
2
|
import { md5 } from "../encoding/md5.js";
|
|
3
3
|
import { LICENSE_STATUS } from "../utils/licenseStatus.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { PLAN_SCOPES } from "../utils/plan.js";
|
|
5
|
+
import { LICENSE_MODELS } from "../utils/licenseModel.js";
|
|
6
6
|
const getDefaultReleaseDate = () => {
|
|
7
7
|
const today = new Date();
|
|
8
8
|
today.setHours(0, 0, 0, 0);
|
|
@@ -11,7 +11,7 @@ const getDefaultReleaseDate = () => {
|
|
|
11
11
|
export function generateReleaseInfo(releaseDate = getDefaultReleaseDate()) {
|
|
12
12
|
return base64Encode(releaseDate.getTime().toString());
|
|
13
13
|
}
|
|
14
|
-
function
|
|
14
|
+
function isPlanScopeSufficient(packageName, planScope) {
|
|
15
15
|
let acceptedScopes;
|
|
16
16
|
if (packageName.includes('-pro')) {
|
|
17
17
|
acceptedScopes = ['pro', 'premium'];
|
|
@@ -20,7 +20,7 @@ function isLicenseScopeSufficient(packageName, licenseScope) {
|
|
|
20
20
|
} else {
|
|
21
21
|
acceptedScopes = [];
|
|
22
22
|
}
|
|
23
|
-
return acceptedScopes.includes(
|
|
23
|
+
return acceptedScopes.includes(planScope);
|
|
24
24
|
}
|
|
25
25
|
const expiryReg = /^.*EXPIRY=([0-9]+),.*$/;
|
|
26
26
|
const PRO_PACKAGES_AVAILABLE_IN_INITIAL_PRO_PLAN = ['x-data-grid-pro', 'x-date-pickers-pro'];
|
|
@@ -39,29 +39,29 @@ const decodeLicenseVersion1 = license => {
|
|
|
39
39
|
expiryTimestamp = null;
|
|
40
40
|
}
|
|
41
41
|
return {
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
planScope: 'pro',
|
|
43
|
+
licenseModel: 'perpetual',
|
|
44
44
|
expiryTimestamp,
|
|
45
45
|
planVersion: 'initial'
|
|
46
46
|
};
|
|
47
47
|
};
|
|
48
48
|
|
|
49
49
|
/**
|
|
50
|
-
* Format: O=${orderNumber},E=${expiryTimestamp},S=${
|
|
50
|
+
* Format: O=${orderNumber},E=${expiryTimestamp},S=${planScope},LM=${licenseModel},PV=${planVersion},KV=2`;
|
|
51
51
|
*/
|
|
52
52
|
const decodeLicenseVersion2 = license => {
|
|
53
53
|
const licenseInfo = {
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
planScope: null,
|
|
55
|
+
licenseModel: null,
|
|
56
56
|
expiryTimestamp: null,
|
|
57
57
|
planVersion: 'initial'
|
|
58
58
|
};
|
|
59
59
|
license.split(',').map(token => token.split('=')).filter(el => el.length === 2).forEach(([key, value]) => {
|
|
60
60
|
if (key === 'S') {
|
|
61
|
-
licenseInfo.
|
|
61
|
+
licenseInfo.planScope = value;
|
|
62
62
|
}
|
|
63
63
|
if (key === 'LM') {
|
|
64
|
-
licenseInfo.
|
|
64
|
+
licenseInfo.licenseModel = value;
|
|
65
65
|
}
|
|
66
66
|
if (key === 'E') {
|
|
67
67
|
const expiryTimestamp = parseInt(value, 10);
|
|
@@ -116,7 +116,7 @@ export function verifyLicense({
|
|
|
116
116
|
status: LICENSE_STATUS.Invalid
|
|
117
117
|
};
|
|
118
118
|
}
|
|
119
|
-
if (license.
|
|
119
|
+
if (license.licenseModel == null || !LICENSE_MODELS.includes(license.licenseModel)) {
|
|
120
120
|
console.error('MUI X: Error checking license. Licensing model not found or invalid!');
|
|
121
121
|
return {
|
|
122
122
|
status: LICENSE_STATUS.Invalid
|
|
@@ -128,7 +128,7 @@ export function verifyLicense({
|
|
|
128
128
|
status: LICENSE_STATUS.Invalid
|
|
129
129
|
};
|
|
130
130
|
}
|
|
131
|
-
if (license.
|
|
131
|
+
if (license.licenseModel === 'perpetual' || process.env.NODE_ENV === 'production') {
|
|
132
132
|
const pkgTimestamp = parseInt(base64Decode(releaseInfo), 10);
|
|
133
133
|
if (Number.isNaN(pkgTimestamp)) {
|
|
134
134
|
throw new Error('MUI X: The release information is invalid. Not able to validate license.');
|
|
@@ -138,7 +138,7 @@ export function verifyLicense({
|
|
|
138
138
|
status: LICENSE_STATUS.ExpiredVersion
|
|
139
139
|
};
|
|
140
140
|
}
|
|
141
|
-
} else if (license.
|
|
141
|
+
} else if (license.licenseModel === 'subscription' || license.licenseModel === 'annual') {
|
|
142
142
|
if (new Date().getTime() > license.expiryTimestamp) {
|
|
143
143
|
if (
|
|
144
144
|
// 30 days grace
|
|
@@ -160,20 +160,20 @@ export function verifyLicense({
|
|
|
160
160
|
};
|
|
161
161
|
}
|
|
162
162
|
}
|
|
163
|
-
if (license.
|
|
164
|
-
console.error('MUI X: Error checking license.
|
|
163
|
+
if (license.planScope == null || !PLAN_SCOPES.includes(license.planScope)) {
|
|
164
|
+
console.error('MUI X: Error checking license. planScope not found or invalid!');
|
|
165
165
|
return {
|
|
166
166
|
status: LICENSE_STATUS.Invalid
|
|
167
167
|
};
|
|
168
168
|
}
|
|
169
|
-
if (!
|
|
169
|
+
if (!isPlanScopeSufficient(packageName, license.planScope)) {
|
|
170
170
|
return {
|
|
171
171
|
status: LICENSE_STATUS.OutOfScope
|
|
172
172
|
};
|
|
173
173
|
}
|
|
174
174
|
|
|
175
175
|
// 'charts-pro' or 'tree-view-pro' can only be used with a newer Pro license
|
|
176
|
-
if (license.planVersion === 'initial' && license.
|
|
176
|
+
if (license.planVersion === 'initial' && license.planScope === 'pro' && !PRO_PACKAGES_AVAILABLE_IN_INITIAL_PRO_PLAN.includes(packageName)) {
|
|
177
177
|
return {
|
|
178
178
|
status: LICENSE_STATUS.NotAvailableInInitialProPlan
|
|
179
179
|
};
|
package/utils/licenseScope.js
DELETED