Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 40 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
## nodejs-license-file [![Build Status](https://travis-ci.org/bushev/nodejs-license-file.svg?branch=master)](https://travis-ci.org/bushev/nodejs-license-file)
# nodejs-license-file

[![Build Status](https://travis-ci.org/bushev/nodejs-license-file.svg?branch=master)](https://travis-ci.org/bushev/nodejs-license-file)

A lightweight License file generator and parser for NodeJS.

Expand All @@ -15,79 +17,75 @@ A lightweight License file generator and parser for NodeJS.
## Generating license file

```javascript
const licenseFile = require('nodejs-license-file');
const licenseFile = require("nodejs-license-file");
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why change the string quotes convention?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My linter did that

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This project does not have an .eslintrc file so you shouldn't be applying your personal preferences to it. It's better to maintain the existing conventions.


const template = [
'====BEGIN LICENSE====',
'{{&licenseVersion}}',
'{{&applicationVersion}}',
'{{&firstName}}',
'{{&lastName}}',
'{{&email}}',
'{{&expirationDate}}',
'{{&serial}}',
'=====END LICENSE====='
].join('\n');
"====BEGIN LICENSE====",
"{{&licenseVersion}}",
"{{&applicationVersion}}",
"{{&firstName}}",
"{{&lastName}}",
"{{&email}}",
"{{&expirationDate}}",
"{{&serial}}",
"=====END LICENSE====="
].join("\n");

try {

const licenseFileContent = licenseFile.generate({
privateKeyPath: 'path/to/key.pem',
privateKeyPath: "path/to/key.pem",
template,
data: {
licenseVersion: '1',
applicationVersion: '1.0.0',
firstName: 'Name',
lastName: 'Last Name',
email: 'some@email.com',
expirationDate: '12/10/2025'
licenseVersion: "1",
applicationVersion: "1.0.0",
firstName: "Name",
lastName: "Last Name",
email: "some@email.com",
expirationDate: "2025-11-15"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why change the date format? Used to be separated by /, and now separated by -.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dayjs handles date with this specific format by default, plus it's less confusing
I didnt know in the first place if it was DD/MM/YYYY or MM/DD/YYYY

}
});

console.log(licenseFileContent);

console.log(licenseFileContent);
} catch (err) {

console.log(err);
}
```

This will produce a license key, which uses the default template and will look similar to this:
```

```txt
====BEGIN LICENSE====
1
1.0.0
Name
Last Name
some@email.com
12/10/2025
2025-11-15
xxxxxxxxxxxxxxxxxxxxx
=====END LICENSE=====
```

## Parse and verify license file

```javascript
const licenseFile = require('nodejs-license-file');
const licenseFile = require("nodejs-license-file");

try {

const data = licenseFile.parse({
publicKeyPath: 'path/to/key.pub',
licenseFilePath: 'path/to/file.lic',
publicKeyPath: "path/to/key.pub",
licenseFilePath: "path/to/file.lic",
template
});

console.log(data);

} catch (err) {

console.log(err);
}
```

There is an execution result:
```

```json
{
valid: true,
serial: 'oZDqoEr2avwhAqwV4HInq9otNzeBeD/azq2yn2jA ...',
Expand All @@ -97,7 +95,7 @@ There is an execution result:
firstName: 'Name',
lastName: 'Last Name',
email: 'some@email.com',
expirationDate: '12/10/2025'
expirationDate: '2025-11-15'
}
}
```
Expand All @@ -107,38 +105,36 @@ NOTICE: All numeric data will be converted to strings after parsing. You need to
## Parse and verify license string

```javascript
const licenseFile = require('nodejs-license-file');
const licenseFile = require("nodejs-license-file");

try {

const licence = `
====BEGIN LICENSE====
1
1.0.0
Name
Last Name
some@email.com
12/10/2025
2025-11-15
xxxxxxxxxxxxxxxxxxxxx
=====END LICENSE=====
`;

const data = licenseFile.parse({
publicKeyPath: 'path/to/key.pub',
publicKeyPath: "path/to/key.pub",
licenseFile: licence,
template
});

console.log(data);

} catch (err) {

console.log(err);
}
```

There is an execution result:
```

```json
{
valid: true,
serial: 'oZDqoEr2avwhAqwV4HInq9otNzeBeD/azq2yn2jA ...',
Expand All @@ -148,7 +144,7 @@ There is an execution result:
firstName: 'Name',
lastName: 'Last Name',
email: 'some@email.com',
expirationDate: '12/10/2025'
expirationDate: '2025-11-15'
}
}
```
Expand Down
15 changes: 14 additions & 1 deletion lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const crypto = require('crypto');
*/
const stringify = require('json-stable-stringify');

const dayjs = require('dayjs');
/**
* LicenseFile Class
*/
Expand Down Expand Up @@ -167,7 +168,7 @@ class LicenseFile {

verify.update(stringify(dataObj.data));

const valid = verify.verify(publicKey, dataObj.serial, 'base64');
const valid = verify.verify(publicKey, dataObj.serial, 'base64') && LicenseFile._isNotExpired(dataObj);

return {
valid: valid,
Expand Down Expand Up @@ -227,6 +228,18 @@ class LicenseFile {

return result;
}

static _isNotExpired(options) {
let data = options.data;

if (typeof options.data === 'object' && typeof data.expirationDate === 'string') {
const expirationDate = data.expirationDate;
const isBefore = dayjs().isBefore(dayjs(expirationDate));
const isSame = dayjs().isSame(dayjs(expirationDate))
return isBefore || isSame;
Copy link
Copy Markdown

@soryy708 soryy708 Dec 6, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I see you're doing is checking if now <= expirationDate. You don't need a library for that.

I believe you can compare two plain JavaScript date objects with the <= operator directly.
If that's hard to grasp, you can also convert them to a UNIX timestamp (a number) and compare those.
https://stackoverflow.com/questions/492994/compare-two-dates-with-javascript

You can get a date object of the current time via the date constructor without parameters new Date(). Alternatively, you can get the UNIX timestamp by calling Date.now().

So, it would be something like:
return (new Date()) <= new Date(expirationDate)
or
return Date.now() <= (new Date(expirationDate)).getTime()

}
return true;
}
}

/**
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
},
"homepage": "https://github.com/bushev/nodejs-license-file",
"dependencies": {
"dayjs": "1.8.17",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's trivial to compare dates in JavaScript, so you don't need a dependency for that.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's easier to manipulate dates with dayjs, which is the lightest date library I've found

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While that's true, the manipulation that you perform is rather trivial even without a library.
In lib/index.js:239 you're just comparing two dates. I'll comment there directly.

"json-stable-stringify": "1.0.1"
}
}
2 changes: 1 addition & 1 deletion test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const FIRST_NAME = 'First Name';
const LAST_NAME = 'Last Name';
const EMAIL = 'some@email.com';
const SOME_NUMBER = 123;
const EXPIRATION_DATE = '2025/09/25';
const EXPIRATION_DATE = '2025-09-25';

const template = [
'====BEGIN LICENSE====',
Expand Down
Loading