@crela/license 1.0.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/LICENSE +21 -0
- package/README.md +111 -0
- package/dist/index.d.ts +91 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +254 -0
- package/dist/index.js.map +1 -0
- package/package.json +52 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Felix Bonetsmüller
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# @crela/license (Node.js / Electron)
|
|
2
|
+
|
|
3
|
+
License verification SDK for tools on the [Crela](https://crela.io) marketplace.
|
|
4
|
+
|
|
5
|
+
Mandatory for paid tools: the review pipeline looks for a per-tool marker inside your binary (KO-10), and this SDK is what puts it there and checks the licence at startup.
|
|
6
|
+
|
|
7
|
+
## Quick start
|
|
8
|
+
|
|
9
|
+
For Node.js and Electron projects, let the init tool wire everything up:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
cd my-tool/
|
|
13
|
+
npx @crela/init
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
It detects your entry point and bundler, fetches the SDK marker via the API, injects `verifyOrExit()`, and patches your bundler config. After that, just run `npm run build`.
|
|
17
|
+
|
|
18
|
+
## How it works
|
|
19
|
+
|
|
20
|
+
The SDK never prompts for a licence key. It reads a JWT signed by the Crela launcher — either from the environment variable `CRELA_LICENSE_JWT` or from a cache file — and verifies it **offline** against an Ed25519 public key. No network call happens.
|
|
21
|
+
|
|
22
|
+
Activation, heartbeat and device management are handled entirely by the Crela launcher, so your tool does not need its own licence UI. Your integration is one call:
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
import { verifyOrExit } from '@crela/license'
|
|
26
|
+
|
|
27
|
+
verifyOrExit('my-tool', process.env.CRELA_SDK_MARKER!)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Manual build-time setup
|
|
31
|
+
|
|
32
|
+
If you do not use `npx @crela/init`, set the variables yourself before building:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# Marker token from the creator dashboard:
|
|
36
|
+
export CRELA_SDK_MARKER=CRELA_SDKv2_xxxxxxxxxxxxxx
|
|
37
|
+
|
|
38
|
+
# Ed25519 public key (64 hex chars) for JWT verification:
|
|
39
|
+
export CRELA_LICENSE_PUBKEY_HEX=abcdef...
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
With esbuild:
|
|
43
|
+
```bash
|
|
44
|
+
esbuild main.ts \
|
|
45
|
+
--define:CRELA_SDK_MARKER=\"$CRELA_SDK_MARKER\" \
|
|
46
|
+
--define:CRELA_LICENSE_PUBKEY_HEX=\"$CRELA_LICENSE_PUBKEY_HEX\"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
With Webpack:
|
|
50
|
+
```js
|
|
51
|
+
new webpack.DefinePlugin({
|
|
52
|
+
CRELA_SDK_MARKER: JSON.stringify(process.env.CRELA_SDK_MARKER),
|
|
53
|
+
CRELA_LICENSE_PUBKEY_HEX: JSON.stringify(process.env.CRELA_LICENSE_PUBKEY_HEX),
|
|
54
|
+
})
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The marker has to survive bundling as a literal string — reading it from a config file at runtime does not satisfy KO-10.
|
|
58
|
+
|
|
59
|
+
## Usage
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
import { verifyOrExit } from '@crela/license'
|
|
63
|
+
|
|
64
|
+
// In electron main.ts, before app.whenReady():
|
|
65
|
+
verifyOrExit('my-tool', CRELA_SDK_MARKER)
|
|
66
|
+
|
|
67
|
+
app.whenReady().then(createWindow)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
On failure: a message on stderr and `process.exit(0xC1)`.
|
|
71
|
+
|
|
72
|
+
## Verification order
|
|
73
|
+
|
|
74
|
+
1. `CRELA_DEV_MODE=1` env → `isDev=true` claims, no verification
|
|
75
|
+
2. `CRELA_LICENSE_JWT` env → verify token
|
|
76
|
+
3. Cache file `<DATA_LOCAL_DIR>/crela/licenses/<slug>.jwt` → verify token
|
|
77
|
+
4. Nothing found → `LicenseError` with code `NOT_LAUNCHED_FROM_CRELA`
|
|
78
|
+
|
|
79
|
+
## Advanced
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
import { LicenseVerifier } from '@crela/license'
|
|
83
|
+
|
|
84
|
+
const verifier = new LicenseVerifier({
|
|
85
|
+
toolSlug: 'my-tool',
|
|
86
|
+
markerToken: CRELA_SDK_MARKER,
|
|
87
|
+
pubkeyHex: CRELA_LICENSE_PUBKEY_HEX,
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
const claims = verifier.verify()
|
|
92
|
+
console.log(`Licence valid, exp=${claims.exp}`)
|
|
93
|
+
} catch (e) {
|
|
94
|
+
console.error(`Licence invalid: ${e.message}`)
|
|
95
|
+
process.exit(1)
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Other languages
|
|
100
|
+
|
|
101
|
+
Crela ships a ready-made SDK for Node.js/Electron and for [Rust/Tauri](https://crates.io/crates/crela-license). For anything else (.NET, Java, Python, C++, Go) there is no SDK — embed the marker string as a compile-time constant and the review will accept it. Enforcing the licence at runtime is then up to you. See the [creator guidelines](https://crela.io/creator-guidelines#sdk).
|
|
102
|
+
|
|
103
|
+
## Tests
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
npm test
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Licence
|
|
110
|
+
|
|
111
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Crela License SDK v3 - Node.js / Electron
|
|
3
|
+
*
|
|
4
|
+
* Pflicht-Integration fuer Tools auf dem Crela-Marktplatz (paid + free).
|
|
5
|
+
* Die SDK liest ein vom Crela-Launcher signiertes JWT entweder aus der
|
|
6
|
+
* Umgebungsvariable `CRELA_LICENSE_JWT` oder aus einer gemeinsamen
|
|
7
|
+
* Cache-Datei und verifiziert es offline gegen einen einkompilierten
|
|
8
|
+
* Ed25519-Public-Key. Es findet kein Netzwerk-Aufruf statt.
|
|
9
|
+
*
|
|
10
|
+
* Typische Nutzung in Electron-`main.ts`:
|
|
11
|
+
*
|
|
12
|
+
* import { verifyOrExit, CRELA_SDK_MARKER } from '@crela/license'
|
|
13
|
+
* verifyOrExit('mein-tool', CRELA_SDK_MARKER)
|
|
14
|
+
*
|
|
15
|
+
* Marker und Public-Key werden ueblicherweise via Bundler-Define beim
|
|
16
|
+
* Build injiziert oder aus einer build-time-generierten Datei gelesen.
|
|
17
|
+
*/
|
|
18
|
+
/** Prefix des v2-Markers; der vollstaendige Token kommt vom Creator-Dashboard. */
|
|
19
|
+
export declare const CRELA_SDK_MARKER_PREFIX: "CRELA_SDKv2_";
|
|
20
|
+
export declare const CRELA_SDK_MARKER_CONST: string | undefined;
|
|
21
|
+
export declare class LicenseError extends Error {
|
|
22
|
+
code: LicenseErrorCode;
|
|
23
|
+
constructor(code: LicenseErrorCode, message: string);
|
|
24
|
+
}
|
|
25
|
+
export type LicenseErrorCode = 'NOT_LAUNCHED_FROM_CRELA' | 'INVALID_JWT_FORMAT' | 'INVALID_SIGNATURE' | 'EXPIRED' | 'WRONG_TOOL' | 'WRONG_DEVICE' | 'MISSING_CLAIM' | 'INVALID_PUBKEY' | 'INVALID_MARKER';
|
|
26
|
+
export interface LicenseClaims {
|
|
27
|
+
/** License-ID (UUID) */
|
|
28
|
+
sub: string;
|
|
29
|
+
/** Tool-Slug */
|
|
30
|
+
tool: string;
|
|
31
|
+
/** Device-Fingerprint */
|
|
32
|
+
fp: string;
|
|
33
|
+
/** Unix-Timestamp Ausstellung */
|
|
34
|
+
iat: number;
|
|
35
|
+
/** Unix-Timestamp Ablauf */
|
|
36
|
+
exp: number;
|
|
37
|
+
/** Grace-Period in Sekunden */
|
|
38
|
+
grace: number;
|
|
39
|
+
/** True wenn CRELA_DEV_MODE=1 (Verifikation uebersprungen) */
|
|
40
|
+
isDev: boolean;
|
|
41
|
+
}
|
|
42
|
+
export interface VerifierOptions {
|
|
43
|
+
/** Tool-Slug, muss mit JWT-Claim `tool` matchen */
|
|
44
|
+
toolSlug: string;
|
|
45
|
+
/** Marker-Token aus dem Creator-Dashboard. Muss mit CRELA_SDKv2_ beginnen. */
|
|
46
|
+
markerToken: string;
|
|
47
|
+
/** Ed25519-Public-Key (32 Bytes hex). Default: BUILD_TIME_PUBKEY_HEX-Konstante. */
|
|
48
|
+
pubkeyHex?: string;
|
|
49
|
+
/** Cache-Pfad ueberschreiben (Default: <DATA_LOCAL>/crela/licenses/<slug>.jwt). */
|
|
50
|
+
cachePath?: string;
|
|
51
|
+
/**
|
|
52
|
+
* Dev-Mode (`CRELA_DEV_MODE=1`) zulassen. Default: FALSE. Muss fuer lokale
|
|
53
|
+
* Entwicklung explizit aktiviert werden; ausgelieferte Tools lassen es aus,
|
|
54
|
+
* damit Endnutzer die Lizenzpruefung nicht per Umgebungsvariable umgehen.
|
|
55
|
+
*/
|
|
56
|
+
allowDevMode?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Lokalen Geraete-Fingerprint ueberschreiben (nur fuer Tests). Production
|
|
59
|
+
* nutzt die machine-id (node-machine-id, original) - dieselbe Quelle wie der
|
|
60
|
+
* Launcher.
|
|
61
|
+
*/
|
|
62
|
+
deviceFp?: string;
|
|
63
|
+
}
|
|
64
|
+
export declare class LicenseVerifier {
|
|
65
|
+
private readonly toolSlug;
|
|
66
|
+
private readonly pubkeyHex;
|
|
67
|
+
private readonly cachePath;
|
|
68
|
+
private readonly allowDevMode;
|
|
69
|
+
private readonly deviceFp;
|
|
70
|
+
constructor(opts: VerifierOptions);
|
|
71
|
+
/**
|
|
72
|
+
* Lokaler Geraete-Fingerprint. Quelle ist node-machine-id (original) - die
|
|
73
|
+
* MachineGuid/IOPlatformUUID/machine-id, exakt das, was der Launcher
|
|
74
|
+
* (machine-uid 0.5) ins JWT schreibt. Ein gesetztes Override hat Vorrang
|
|
75
|
+
* (Tests). Liefert null, wenn die ID nicht ermittelbar ist.
|
|
76
|
+
*/
|
|
77
|
+
private resolveDeviceFp;
|
|
78
|
+
verify(): LicenseClaims;
|
|
79
|
+
/** Bei Fehler: stderr-Meldung + process.exit(0xC1). */
|
|
80
|
+
verifyOrExit(): LicenseClaims;
|
|
81
|
+
private resolveToken;
|
|
82
|
+
private resolveCachePath;
|
|
83
|
+
private readCacheFile;
|
|
84
|
+
private devClaims;
|
|
85
|
+
private verifyJwt;
|
|
86
|
+
}
|
|
87
|
+
/** Convenience: verifiziert und exitet bei Fehler. */
|
|
88
|
+
export declare function verifyOrExit(toolSlug: string, markerToken: string, pubkeyHex?: string): LicenseClaims;
|
|
89
|
+
/** Fingerprint-Helfer (oeffentlich fuer Apps die ihn loggen). */
|
|
90
|
+
export declare function deviceFingerprint(): string;
|
|
91
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AASH,kFAAkF;AAClF,eAAO,MAAM,uBAAuB,EAAG,cAAuB,CAAA;AAY9D,eAAO,MAAM,sBAAsB,EAAE,MAAM,GAAG,SAC0B,CAAA;AAIxE,qBAAa,YAAa,SAAQ,KAAK;IAClB,IAAI,EAAE,gBAAgB;gBAAtB,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM;CAI3D;AAED,MAAM,MAAM,gBAAgB,GACxB,yBAAyB,GACzB,oBAAoB,GACpB,mBAAmB,GACnB,SAAS,GACT,YAAY,GACZ,cAAc,GACd,eAAe,GACf,gBAAgB,GAChB,gBAAgB,CAAA;AAEpB,MAAM,WAAW,aAAa;IAC5B,wBAAwB;IACxB,GAAG,EAAE,MAAM,CAAA;IACX,gBAAgB;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,yBAAyB;IACzB,EAAE,EAAE,MAAM,CAAA;IACV,iCAAiC;IACjC,GAAG,EAAE,MAAM,CAAA;IACX,4BAA4B;IAC5B,GAAG,EAAE,MAAM,CAAA;IACX,+BAA+B;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,8DAA8D;IAC9D,KAAK,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAA;IAChB,8EAA8E;IAC9E,WAAW,EAAE,MAAM,CAAA;IACnB,mFAAmF;IACnF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,mFAAmF;IACnF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAiBD,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAQ;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoB;IAC9C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;gBAEjC,IAAI,EAAE,eAAe;IAYjC;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAavB,MAAM,IAAI,aAAa;IAoCvB,uDAAuD;IACvD,YAAY,IAAI,aAAa;IAW7B,OAAO,CAAC,YAAY;IAapB,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,SAAS;IAajB,OAAO,CAAC,SAAS;CAgDlB;AAED,sDAAsD;AACtD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,aAAa,CAErG;AAED,iEAAiE;AACjE,wBAAgB,iBAAiB,IAAI,MAAM,CAM1C"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Crela License SDK v3 - Node.js / Electron
|
|
3
|
+
*
|
|
4
|
+
* Pflicht-Integration fuer Tools auf dem Crela-Marktplatz (paid + free).
|
|
5
|
+
* Die SDK liest ein vom Crela-Launcher signiertes JWT entweder aus der
|
|
6
|
+
* Umgebungsvariable `CRELA_LICENSE_JWT` oder aus einer gemeinsamen
|
|
7
|
+
* Cache-Datei und verifiziert es offline gegen einen einkompilierten
|
|
8
|
+
* Ed25519-Public-Key. Es findet kein Netzwerk-Aufruf statt.
|
|
9
|
+
*
|
|
10
|
+
* Typische Nutzung in Electron-`main.ts`:
|
|
11
|
+
*
|
|
12
|
+
* import { verifyOrExit, CRELA_SDK_MARKER } from '@crela/license'
|
|
13
|
+
* verifyOrExit('mein-tool', CRELA_SDK_MARKER)
|
|
14
|
+
*
|
|
15
|
+
* Marker und Public-Key werden ueblicherweise via Bundler-Define beim
|
|
16
|
+
* Build injiziert oder aus einer build-time-generierten Datei gelesen.
|
|
17
|
+
*/
|
|
18
|
+
import { readFileSync } from 'node:fs';
|
|
19
|
+
import { existsSync } from 'node:fs';
|
|
20
|
+
import { join } from 'node:path';
|
|
21
|
+
import { homedir, hostname, platform } from 'node:os';
|
|
22
|
+
import { createRequire } from 'node:module';
|
|
23
|
+
import { createHash, createPublicKey, verify as cryptoVerify } from 'node:crypto';
|
|
24
|
+
/** Prefix des v2-Markers; der vollstaendige Token kommt vom Creator-Dashboard. */
|
|
25
|
+
export const CRELA_SDK_MARKER_PREFIX = 'CRELA_SDKv2_';
|
|
26
|
+
export const CRELA_SDK_MARKER_CONST = typeof CRELA_SDK_MARKER !== 'undefined' ? CRELA_SDK_MARKER : undefined;
|
|
27
|
+
const SKEW_SECONDS = 300; // 5 Minuten Clock-Skew-Toleranz
|
|
28
|
+
export class LicenseError extends Error {
|
|
29
|
+
code;
|
|
30
|
+
constructor(code, message) {
|
|
31
|
+
super(message);
|
|
32
|
+
this.code = code;
|
|
33
|
+
this.name = 'LicenseError';
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Production-Public-Key fuer Ed25519-JWT-Verifikation gegen crela.io.
|
|
38
|
+
* Pubkey aus dem `x`-Feld der Production CRELA_LICENSE_SIGNING_JWK,
|
|
39
|
+
* base64url-decoded und als 32-Byte-Hex. Wird als Default genutzt, kann
|
|
40
|
+
* via Bundler-Define (CRELA_LICENSE_PUBKEY_HEX) ueberschrieben werden
|
|
41
|
+
* (z.B. fuer Self-Hosted-Crela-Instanzen).
|
|
42
|
+
*/
|
|
43
|
+
const PRODUCTION_PUBKEY_HEX = 'c6c37639c659cb9168d6af510d9696d141d980c5145212232f800b21a8210231';
|
|
44
|
+
const BUILD_TIME_PUBKEY_HEX = typeof CRELA_LICENSE_PUBKEY_HEX !== 'undefined' && CRELA_LICENSE_PUBKEY_HEX.length === 64
|
|
45
|
+
? CRELA_LICENSE_PUBKEY_HEX
|
|
46
|
+
: PRODUCTION_PUBKEY_HEX;
|
|
47
|
+
export class LicenseVerifier {
|
|
48
|
+
toolSlug;
|
|
49
|
+
pubkeyHex;
|
|
50
|
+
cachePath;
|
|
51
|
+
allowDevMode;
|
|
52
|
+
deviceFp;
|
|
53
|
+
constructor(opts) {
|
|
54
|
+
if (!opts.toolSlug)
|
|
55
|
+
throw new LicenseError('MISSING_CLAIM', 'toolSlug ist erforderlich');
|
|
56
|
+
if (!opts.markerToken || !opts.markerToken.startsWith(CRELA_SDK_MARKER_PREFIX)) {
|
|
57
|
+
throw new LicenseError('INVALID_MARKER', `markerToken muss mit "${CRELA_SDK_MARKER_PREFIX}" beginnen`);
|
|
58
|
+
}
|
|
59
|
+
this.toolSlug = opts.toolSlug;
|
|
60
|
+
this.pubkeyHex = opts.pubkeyHex ?? BUILD_TIME_PUBKEY_HEX;
|
|
61
|
+
this.cachePath = opts.cachePath;
|
|
62
|
+
this.allowDevMode = opts.allowDevMode ?? false;
|
|
63
|
+
this.deviceFp = opts.deviceFp;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Lokaler Geraete-Fingerprint. Quelle ist node-machine-id (original) - die
|
|
67
|
+
* MachineGuid/IOPlatformUUID/machine-id, exakt das, was der Launcher
|
|
68
|
+
* (machine-uid 0.5) ins JWT schreibt. Ein gesetztes Override hat Vorrang
|
|
69
|
+
* (Tests). Liefert null, wenn die ID nicht ermittelbar ist.
|
|
70
|
+
*/
|
|
71
|
+
resolveDeviceFp() {
|
|
72
|
+
if (this.deviceFp !== undefined)
|
|
73
|
+
return this.deviceFp;
|
|
74
|
+
try {
|
|
75
|
+
const mod = createRequire(import.meta.url)('node-machine-id');
|
|
76
|
+
const id = mod.machineIdSync(true);
|
|
77
|
+
return id && id.length > 0 ? id : null;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
verify() {
|
|
84
|
+
if (this.allowDevMode && process.env.CRELA_DEV_MODE === '1') {
|
|
85
|
+
return this.devClaims();
|
|
86
|
+
}
|
|
87
|
+
const token = this.resolveToken();
|
|
88
|
+
const claims = this.verifyJwt(token);
|
|
89
|
+
if (claims.tool !== this.toolSlug) {
|
|
90
|
+
throw new LicenseError('WRONG_TOOL', `JWT ist fuer "${claims.tool}" ausgestellt, erwartet "${this.toolSlug}"`);
|
|
91
|
+
}
|
|
92
|
+
const now = nowSeconds();
|
|
93
|
+
if (claims.exp + SKEW_SECONDS < now) {
|
|
94
|
+
throw new LicenseError('EXPIRED', 'JWT ist abgelaufen');
|
|
95
|
+
}
|
|
96
|
+
// Geraetebindung: der fp-Claim muss zur lokalen Maschine passen, sonst
|
|
97
|
+
// laesst sich ein gueltiges Token einfach auf beliebig viele Rechner
|
|
98
|
+
// kopieren. Quelle ist node-machine-id (original) - dieselbe ID, die der
|
|
99
|
+
// Launcher (machine-uid) ins JWT schreibt. Fail-closed, wenn die ID nicht
|
|
100
|
+
// ermittelbar ist (ein vom Launcher gestartetes Tool hat immer eine).
|
|
101
|
+
const localFp = this.resolveDeviceFp();
|
|
102
|
+
if (localFp === null || localFp.toLowerCase() !== claims.fp.toLowerCase()) {
|
|
103
|
+
throw new LicenseError('WRONG_DEVICE', 'JWT ist an ein anderes Geraet gebunden (Lizenz wurde auf eine fremde Maschine kopiert)');
|
|
104
|
+
}
|
|
105
|
+
return claims;
|
|
106
|
+
}
|
|
107
|
+
/** Bei Fehler: stderr-Meldung + process.exit(0xC1). */
|
|
108
|
+
verifyOrExit() {
|
|
109
|
+
try {
|
|
110
|
+
return this.verify();
|
|
111
|
+
}
|
|
112
|
+
catch (e) {
|
|
113
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
114
|
+
process.stderr.write(`crela-license: ${msg}\n`);
|
|
115
|
+
process.stderr.write('Bitte starte diese App ueber den Crela Launcher.\n');
|
|
116
|
+
process.exit(0xc1);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
resolveToken() {
|
|
120
|
+
const envToken = process.env.CRELA_LICENSE_JWT;
|
|
121
|
+
if (envToken && envToken.length > 0)
|
|
122
|
+
return envToken;
|
|
123
|
+
const cached = this.readCacheFile();
|
|
124
|
+
if (cached)
|
|
125
|
+
return cached;
|
|
126
|
+
throw new LicenseError('NOT_LAUNCHED_FROM_CRELA', 'Kein Lizenz-Token gefunden (weder env-var noch Cache-File). Bitte starte diese App ueber den Crela Launcher.');
|
|
127
|
+
}
|
|
128
|
+
resolveCachePath() {
|
|
129
|
+
if (this.cachePath)
|
|
130
|
+
return this.cachePath;
|
|
131
|
+
return join(dataLocalDir(), 'crela', 'licenses', `${this.toolSlug}.jwt`);
|
|
132
|
+
}
|
|
133
|
+
readCacheFile() {
|
|
134
|
+
const path = this.resolveCachePath();
|
|
135
|
+
if (!existsSync(path))
|
|
136
|
+
return null;
|
|
137
|
+
try {
|
|
138
|
+
const raw = readFileSync(path, 'utf-8').trim();
|
|
139
|
+
return raw.length > 0 ? raw : null;
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
devClaims() {
|
|
146
|
+
const now = nowSeconds();
|
|
147
|
+
return {
|
|
148
|
+
sub: 'dev-mode',
|
|
149
|
+
tool: this.toolSlug,
|
|
150
|
+
fp: 'dev-fingerprint',
|
|
151
|
+
iat: now,
|
|
152
|
+
exp: now + 86_400,
|
|
153
|
+
grace: 86_400,
|
|
154
|
+
isDev: true,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
verifyJwt(token) {
|
|
158
|
+
if (!this.pubkeyHex || this.pubkeyHex.length !== 64) {
|
|
159
|
+
throw new LicenseError('INVALID_PUBKEY', 'Ed25519-Public-Key fehlt oder ist ungueltig');
|
|
160
|
+
}
|
|
161
|
+
const parts = token.split('.');
|
|
162
|
+
if (parts.length !== 3) {
|
|
163
|
+
throw new LicenseError('INVALID_JWT_FORMAT', 'JWT-Format ungueltig');
|
|
164
|
+
}
|
|
165
|
+
let payloadBytes;
|
|
166
|
+
let sigBytes;
|
|
167
|
+
try {
|
|
168
|
+
payloadBytes = base64UrlDecode(parts[1]);
|
|
169
|
+
sigBytes = base64UrlDecode(parts[2]);
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
throw new LicenseError('INVALID_JWT_FORMAT', 'JWT-Base64-Decode fehlgeschlagen');
|
|
173
|
+
}
|
|
174
|
+
if (sigBytes.length !== 64) {
|
|
175
|
+
throw new LicenseError('INVALID_JWT_FORMAT', `JWT-Signatur falsche Laenge: ${sigBytes.length}`);
|
|
176
|
+
}
|
|
177
|
+
const signingInput = Buffer.from(`${parts[0]}.${parts[1]}`);
|
|
178
|
+
const pubkey = ed25519PublicKey(this.pubkeyHex);
|
|
179
|
+
const ok = cryptoVerify(null, signingInput, pubkey, sigBytes);
|
|
180
|
+
if (!ok) {
|
|
181
|
+
throw new LicenseError('INVALID_SIGNATURE', 'JWT-Signatur konnte nicht verifiziert werden');
|
|
182
|
+
}
|
|
183
|
+
let raw;
|
|
184
|
+
try {
|
|
185
|
+
raw = JSON.parse(payloadBytes.toString('utf-8'));
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
throw new LicenseError('INVALID_JWT_FORMAT', 'JWT-Payload ist kein gueltiges JSON');
|
|
189
|
+
}
|
|
190
|
+
return {
|
|
191
|
+
sub: requireString(raw, 'sub'),
|
|
192
|
+
tool: requireString(raw, 'tool'),
|
|
193
|
+
fp: requireString(raw, 'fp'),
|
|
194
|
+
iat: typeof raw.iat === 'number' ? raw.iat : 0,
|
|
195
|
+
exp: requireNumber(raw, 'exp'),
|
|
196
|
+
grace: typeof raw.grace === 'number' ? raw.grace : 0,
|
|
197
|
+
isDev: false,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
/** Convenience: verifiziert und exitet bei Fehler. */
|
|
202
|
+
export function verifyOrExit(toolSlug, markerToken, pubkeyHex) {
|
|
203
|
+
return new LicenseVerifier({ toolSlug, markerToken, pubkeyHex }).verifyOrExit();
|
|
204
|
+
}
|
|
205
|
+
/** Fingerprint-Helfer (oeffentlich fuer Apps die ihn loggen). */
|
|
206
|
+
export function deviceFingerprint() {
|
|
207
|
+
const h = createHash('sha256');
|
|
208
|
+
try {
|
|
209
|
+
h.update(hostname());
|
|
210
|
+
}
|
|
211
|
+
catch { /* ignore */ }
|
|
212
|
+
// Note: kein MAC-Fallback in Node-SDK; Apps die exakte FP brauchen rufen
|
|
213
|
+
// direkt die node-mac-address lib.
|
|
214
|
+
return h.digest('hex');
|
|
215
|
+
}
|
|
216
|
+
function base64UrlDecode(s) {
|
|
217
|
+
const pad = s.length % 4 === 0 ? '' : '='.repeat(4 - (s.length % 4));
|
|
218
|
+
return Buffer.from(s.replace(/-/g, '+').replace(/_/g, '/') + pad, 'base64');
|
|
219
|
+
}
|
|
220
|
+
function ed25519PublicKey(hex) {
|
|
221
|
+
// SubjectPublicKeyInfo DER prefix fuer Ed25519: 302a300506032b6570032100
|
|
222
|
+
const prefix = Buffer.from('302a300506032b6570032100', 'hex');
|
|
223
|
+
const keyBytes = Buffer.from(hex, 'hex');
|
|
224
|
+
const spki = Buffer.concat([prefix, keyBytes]);
|
|
225
|
+
return createPublicKey({ key: spki, format: 'der', type: 'spki' });
|
|
226
|
+
}
|
|
227
|
+
function dataLocalDir() {
|
|
228
|
+
const p = platform();
|
|
229
|
+
if (p === 'win32') {
|
|
230
|
+
return process.env.LOCALAPPDATA ?? join(homedir(), 'AppData', 'Local');
|
|
231
|
+
}
|
|
232
|
+
if (p === 'darwin') {
|
|
233
|
+
return join(homedir(), 'Library', 'Application Support');
|
|
234
|
+
}
|
|
235
|
+
return process.env.XDG_DATA_HOME ?? join(homedir(), '.local', 'share');
|
|
236
|
+
}
|
|
237
|
+
function nowSeconds() {
|
|
238
|
+
return Math.floor(Date.now() / 1000);
|
|
239
|
+
}
|
|
240
|
+
function requireString(o, key) {
|
|
241
|
+
const v = o[key];
|
|
242
|
+
if (typeof v !== 'string' || v.length === 0) {
|
|
243
|
+
throw new LicenseError('MISSING_CLAIM', `JWT-Claim "${key}" fehlt oder ist kein String`);
|
|
244
|
+
}
|
|
245
|
+
return v;
|
|
246
|
+
}
|
|
247
|
+
function requireNumber(o, key) {
|
|
248
|
+
const v = o[key];
|
|
249
|
+
if (typeof v !== 'number') {
|
|
250
|
+
throw new LicenseError('MISSING_CLAIM', `JWT-Claim "${key}" fehlt oder ist keine Number`);
|
|
251
|
+
}
|
|
252
|
+
return v;
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@crela/license",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "License verification SDK for Crela marketplace tools (Node.js / Electron). Reads JWT from launcher-injected env var or cache file, verifies offline via Ed25519.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"module": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"README.md",
|
|
18
|
+
"LICENSE"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsc",
|
|
22
|
+
"test": "vitest run",
|
|
23
|
+
"prepublishOnly": "npm run build && npm test"
|
|
24
|
+
},
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=18"
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"crela",
|
|
30
|
+
"license",
|
|
31
|
+
"drm",
|
|
32
|
+
"marketplace",
|
|
33
|
+
"electron"
|
|
34
|
+
],
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"access": "public"
|
|
38
|
+
},
|
|
39
|
+
"homepage": "https://crela.io/docs#sdk-marker",
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "https://github.com/Boniihhh/Crela",
|
|
43
|
+
"directory": "packages/sdk-node"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"typescript": "^5.5.0",
|
|
47
|
+
"vitest": "^4.1.7"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"node-machine-id": "^1.1.12"
|
|
51
|
+
}
|
|
52
|
+
}
|