project-shield 1.0.2 → 1.1.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/dist/index.js +62 -20
- package/dist/index.js.map +1 -1
- package/dist/license/commands.d.ts +17 -0
- package/dist/license/commands.d.ts.map +1 -0
- package/dist/license/commands.js +154 -0
- package/dist/license/commands.js.map +1 -0
- package/dist/license/gate.d.ts +14 -0
- package/dist/license/gate.d.ts.map +1 -0
- package/dist/license/gate.js +35 -0
- package/dist/license/gate.js.map +1 -0
- package/dist/license/http.d.ts +7 -0
- package/dist/license/http.d.ts.map +1 -0
- package/dist/license/http.js +89 -0
- package/dist/license/http.js.map +1 -0
- package/dist/license/index.d.ts +6 -0
- package/dist/license/index.d.ts.map +1 -0
- package/dist/license/index.js +20 -0
- package/dist/license/index.js.map +1 -0
- package/dist/license/storage.d.ts +31 -0
- package/dist/license/storage.d.ts.map +1 -0
- package/dist/license/storage.js +138 -0
- package/dist/license/storage.js.map +1 -0
- package/dist/license/types.d.ts +55 -0
- package/dist/license/types.d.ts.map +1 -0
- package/dist/license/types.js +4 -0
- package/dist/license/types.js.map +1 -0
- package/dist/license/usage.d.ts +22 -0
- package/dist/license/usage.d.ts.map +1 -0
- package/dist/license/usage.js +60 -0
- package/dist/license/usage.js.map +1 -0
- package/dist/license/validator.d.ts +28 -0
- package/dist/license/validator.d.ts.map +1 -0
- package/dist/license/validator.js +108 -0
- package/dist/license/validator.js.map +1 -0
- package/dist/output/terminal.d.ts +8 -2
- package/dist/output/terminal.d.ts.map +1 -1
- package/dist/output/terminal.js +21 -2
- package/dist/output/terminal.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -46,6 +46,10 @@ const terminal_js_1 = require("./output/terminal.js");
|
|
|
46
46
|
const fixit_js_1 = require("./output/fixit.js");
|
|
47
47
|
const evidence_js_1 = require("./output/evidence.js");
|
|
48
48
|
const failsafe_js_1 = require("./integrity/failsafe.js");
|
|
49
|
+
const validator_js_1 = require("./license/validator.js");
|
|
50
|
+
const usage_js_1 = require("./license/usage.js");
|
|
51
|
+
const gate_js_1 = require("./license/gate.js");
|
|
52
|
+
const commands_js_1 = require("./license/commands.js");
|
|
49
53
|
const program = new commander_1.Command();
|
|
50
54
|
program
|
|
51
55
|
.name('project-shield')
|
|
@@ -59,11 +63,22 @@ program
|
|
|
59
63
|
.option('-i, --ignore <path>', 'Path to .shieldignore file')
|
|
60
64
|
.option('-r, --ruleset <path>', 'Path to ruleset JSON file')
|
|
61
65
|
.option('-b, --badge <path>', 'Output path for SVG badge', '')
|
|
62
|
-
.option('--pro', 'Generate Pro badge (no watermark)', false)
|
|
63
66
|
.option('--fix', 'Show fix-it remediation guides', false)
|
|
64
67
|
.option('--evidence <path>', 'Output path for evidence pack (JSON + PDF)')
|
|
65
68
|
.action(async (targetPath, options) => {
|
|
66
69
|
try {
|
|
70
|
+
// ─── License validation ───────────────────────────────
|
|
71
|
+
const tier = await (0, validator_js_1.validateLicense)();
|
|
72
|
+
const gate = (0, gate_js_1.getFeatureGate)(tier);
|
|
73
|
+
// Check scan limit
|
|
74
|
+
const scanCheck = (0, usage_js_1.canScan)(tier);
|
|
75
|
+
if (!scanCheck.allowed) {
|
|
76
|
+
console.error(`Error: ${scanCheck.reason}`);
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
// Show tier header
|
|
80
|
+
const tierLabel = tier.isPro ? '\x1b[32mPro\x1b[0m' : 'Free';
|
|
81
|
+
console.log(`Tier: ${tierLabel} (${tier.scansUsed}/${tier.maxScans} scans)`);
|
|
67
82
|
const resolvedPath = path.resolve(targetPath);
|
|
68
83
|
const format = options.format;
|
|
69
84
|
// Load ruleset info for display
|
|
@@ -77,39 +92,44 @@ program
|
|
|
77
92
|
// Calculate score and lock status
|
|
78
93
|
const score = (0, score_js_1.calculateScore)(result);
|
|
79
94
|
const lockStatus = (0, lock_js_1.getLockStatus)(score);
|
|
80
|
-
const seal = (0, seal_js_1.sealResult)(result, score, ruleset.version, { isPro:
|
|
95
|
+
const seal = (0, seal_js_1.sealResult)(result, score, ruleset.version, { isPro: gate.canGenerateSealUUID });
|
|
81
96
|
if (format === 'json') {
|
|
82
|
-
const jsonObj = JSON.parse((0, terminal_js_1.formatJsonOutput)(result, score, seal));
|
|
97
|
+
const jsonObj = JSON.parse((0, terminal_js_1.formatJsonOutput)(result, score, seal, { isPro: gate.isPro }));
|
|
83
98
|
if (options.fix) {
|
|
84
|
-
const guides = (0, fixit_js_1.getFixitGuides)(result, { isPro:
|
|
85
|
-
jsonObj.fixit = (0, fixit_js_1.formatFixitJson)(guides,
|
|
99
|
+
const guides = (0, fixit_js_1.getFixitGuides)(result, { isPro: gate.canSeeFullFixit });
|
|
100
|
+
jsonObj.fixit = (0, fixit_js_1.formatFixitJson)(guides, gate.canSeeFullFixit);
|
|
86
101
|
}
|
|
87
102
|
console.log(JSON.stringify(jsonObj, null, 2));
|
|
88
103
|
}
|
|
89
104
|
else {
|
|
90
|
-
console.log((0, terminal_js_1.formatTerminalOutput)(result, ruleset.version, ruleset.sha256, score, lockStatus));
|
|
105
|
+
console.log((0, terminal_js_1.formatTerminalOutput)(result, ruleset.version, ruleset.sha256, score, lockStatus, { isPro: gate.isPro }));
|
|
91
106
|
if (options.fix) {
|
|
92
|
-
const guides = (0, fixit_js_1.getFixitGuides)(result, { isPro:
|
|
93
|
-
console.log((0, fixit_js_1.formatFixitTerminal)(guides,
|
|
107
|
+
const guides = (0, fixit_js_1.getFixitGuides)(result, { isPro: gate.canSeeFullFixit });
|
|
108
|
+
console.log((0, fixit_js_1.formatFixitTerminal)(guides, gate.canSeeFullFixit));
|
|
94
109
|
}
|
|
95
110
|
}
|
|
96
|
-
// Evidence Pack generation
|
|
111
|
+
// Evidence Pack generation (Pro only)
|
|
97
112
|
if (options.evidence) {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
113
|
+
if (!gate.canGenerateEvidence) {
|
|
114
|
+
console.error('Error: Evidence Pack is a Pro feature. Upgrade: https://project-shield.dev/pro');
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
const evidencePath = path.resolve(options.evidence);
|
|
118
|
+
const pack = (0, evidence_js_1.generateEvidenceJSON)(result, score, lockStatus, seal, {
|
|
119
|
+
scanTarget: resolvedPath,
|
|
120
|
+
rulesetHash: ruleset.sha256,
|
|
121
|
+
rulesetVersion: ruleset.version,
|
|
122
|
+
});
|
|
123
|
+
(0, evidence_js_1.saveEvidenceJSON)(pack, `${evidencePath}.json`);
|
|
124
|
+
console.log(`Evidence JSON saved to: ${evidencePath}.json`);
|
|
125
|
+
await (0, evidence_js_1.generateEvidencePDF)(pack, `${evidencePath}.pdf`);
|
|
126
|
+
console.log(`Evidence PDF saved to: ${evidencePath}.pdf`);
|
|
127
|
+
}
|
|
108
128
|
}
|
|
109
129
|
// Badge generation
|
|
110
130
|
if (options.badge) {
|
|
111
131
|
try {
|
|
112
|
-
const svg = (0, badge_js_1.generateBadge)(score, lockStatus, { isPro:
|
|
132
|
+
const svg = (0, badge_js_1.generateBadge)(score, lockStatus, { isPro: gate.canSeeCleanBadge });
|
|
113
133
|
const badgePath = path.resolve(options.badge);
|
|
114
134
|
(0, badge_js_1.saveBadge)(svg, badgePath);
|
|
115
135
|
console.log(`Badge saved to: ${badgePath}`);
|
|
@@ -123,6 +143,8 @@ program
|
|
|
123
143
|
}
|
|
124
144
|
}
|
|
125
145
|
}
|
|
146
|
+
// Record the scan AFTER successful completion
|
|
147
|
+
(0, usage_js_1.recordScan)();
|
|
126
148
|
// Exit with code 1 if critical findings
|
|
127
149
|
const hasCritical = result.summary.critical > 0 ||
|
|
128
150
|
result.summary.confirmedPii > 0 ||
|
|
@@ -147,5 +169,25 @@ program
|
|
|
147
169
|
process.exit(1);
|
|
148
170
|
}
|
|
149
171
|
});
|
|
172
|
+
// ─── License commands ─────────────────────────────────────────
|
|
173
|
+
program
|
|
174
|
+
.command('activate')
|
|
175
|
+
.description('Activate a Pro license key')
|
|
176
|
+
.argument('<key>', 'License key (PSH-XXXX-XXXX-XXXX-XXXX)')
|
|
177
|
+
.action(async (key) => {
|
|
178
|
+
await (0, commands_js_1.activateCommand)(key);
|
|
179
|
+
});
|
|
180
|
+
program
|
|
181
|
+
.command('deactivate')
|
|
182
|
+
.description('Deactivate the current license')
|
|
183
|
+
.action(async () => {
|
|
184
|
+
await (0, commands_js_1.deactivateCommand)();
|
|
185
|
+
});
|
|
186
|
+
program
|
|
187
|
+
.command('status')
|
|
188
|
+
.description('Show license and usage status')
|
|
189
|
+
.action(async () => {
|
|
190
|
+
await (0, commands_js_1.statusCommand)();
|
|
191
|
+
});
|
|
150
192
|
program.parse();
|
|
151
193
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,yCAAoC;AACpC,gDAAkC;AAClC,mDAA2C;AAC3C,uDAAqD;AACrD,iDAAoD;AACpD,+CAAkD;AAClD,iDAAiD;AACjD,gDAA+E;AAC/E,sDAA8E;AAC9E,gDAAyF;AACzF,sDAAmG;AACnG,yDAIiC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,yCAAoC;AACpC,gDAAkC;AAClC,mDAA2C;AAC3C,uDAAqD;AACrD,iDAAoD;AACpD,+CAAkD;AAClD,iDAAiD;AACjD,gDAA+E;AAC/E,sDAA8E;AAC9E,gDAAyF;AACzF,sDAAmG;AACnG,yDAIiC;AACjC,yDAAyD;AACzD,iDAAyD;AACzD,+CAAmD;AACnD,uDAA0F;AAE1F,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,gBAAgB,CAAC;KACtB,WAAW,CAAC,8CAA8C,CAAC;KAC3D,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,0DAA0D,CAAC;KACvE,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;KAClC,MAAM,CAAC,uBAAuB,EAAE,kCAAkC,EAAE,UAAU,CAAC;KAC/E,MAAM,CAAC,qBAAqB,EAAE,4BAA4B,CAAC;KAC3D,MAAM,CAAC,sBAAsB,EAAE,2BAA2B,CAAC;KAC3D,MAAM,CAAC,oBAAoB,EAAE,2BAA2B,EAAE,EAAE,CAAC;KAC7D,MAAM,CAAC,OAAO,EAAE,gCAAgC,EAAE,KAAK,CAAC;KACxD,MAAM,CAAC,mBAAmB,EAAE,4CAA4C,CAAC;KACzE,MAAM,CAAC,KAAK,EAAE,UAAkB,EAAE,OAOlC,EAAE,EAAE;IACH,IAAI,CAAC;QACH,yDAAyD;QACzD,MAAM,IAAI,GAAG,MAAM,IAAA,8BAAe,GAAE,CAAC;QACrC,MAAM,IAAI,GAAG,IAAA,wBAAc,EAAC,IAAI,CAAC,CAAC;QAElC,mBAAmB;QACnB,MAAM,SAAS,GAAG,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC;QAChC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;YACvB,OAAO,CAAC,KAAK,CAAC,UAAU,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;YAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,mBAAmB;QACnB,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,MAAM,CAAC;QAC7D,OAAO,CAAC,GAAG,CAAC,SAAS,SAAS,KAAK,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,QAAQ,SAAS,CAAC,CAAC;QAE7E,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,OAAO,CAAC,MAA6B,CAAC;QAErD,gCAAgC;QAChC,MAAM,OAAO,GAAG,IAAA,wBAAW,EAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAE7C,MAAM,MAAM,GAAG,MAAM,IAAA,gBAAI,EAAC;YACxB,UAAU,EAAE,YAAY;YACxB,MAAM;YACN,UAAU,EAAE,OAAO,CAAC,MAAM;YAC1B,WAAW,EAAE,OAAO,CAAC,OAAO;SAC7B,CAAC,CAAC;QAEH,kCAAkC;QAClC,MAAM,KAAK,GAAG,IAAA,yBAAc,EAAC,MAAM,CAAC,CAAC;QACrC,MAAM,UAAU,GAAG,IAAA,uBAAa,EAAC,KAAK,CAAC,CAAC;QACxC,MAAM,IAAI,GAAG,IAAA,oBAAU,EAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC;QAE7F,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YACtB,MAAM,OAAO,GAA4B,IAAI,CAAC,KAAK,CACjD,IAAA,8BAAgB,EAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAC7D,CAAC;YACF,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;gBAChB,MAAM,MAAM,GAAG,IAAA,yBAAc,EAAC,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC;gBACvE,OAAO,CAAC,KAAK,GAAG,IAAA,0BAAe,EAAC,MAAM,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;YAChE,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAChD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,IAAA,kCAAoB,EAAC,MAAM,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YACrH,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;gBAChB,MAAM,MAAM,GAAG,IAAA,yBAAc,EAAC,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC;gBACvE,OAAO,CAAC,GAAG,CAAC,IAAA,8BAAmB,EAAC,MAAM,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;YACjE,CAAC;QACH,CAAC;QAED,sCAAsC;QACtC,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACrB,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC9B,OAAO,CAAC,KAAK,CAAC,gFAAgF,CAAC,CAAC;YAClG,CAAC;iBAAM,CAAC;gBACN,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;gBACpD,MAAM,IAAI,GAAG,IAAA,kCAAoB,EAAC,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE;oBACjE,UAAU,EAAE,YAAY;oBACxB,WAAW,EAAE,OAAO,CAAC,MAAM;oBAC3B,cAAc,EAAE,OAAO,CAAC,OAAO;iBAChC,CAAC,CAAC;gBACH,IAAA,8BAAgB,EAAC,IAAI,EAAE,GAAG,YAAY,OAAO,CAAC,CAAC;gBAC/C,OAAO,CAAC,GAAG,CAAC,2BAA2B,YAAY,OAAO,CAAC,CAAC;gBAC5D,MAAM,IAAA,iCAAmB,EAAC,IAAI,EAAE,GAAG,YAAY,MAAM,CAAC,CAAC;gBACvD,OAAO,CAAC,GAAG,CAAC,0BAA0B,YAAY,MAAM,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC;QAED,mBAAmB;QACnB,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YAClB,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,IAAA,wBAAa,EAAC,KAAK,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC;gBAC/E,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gBAC9C,IAAA,oBAAS,EAAC,GAAG,EAAE,SAAS,CAAC,CAAC;gBAC1B,OAAO,CAAC,GAAG,CAAC,mBAAmB,SAAS,EAAE,CAAC,CAAC;YAC9C,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,KAAK,YAAY,2BAAgB,EAAE,CAAC;oBACtC,OAAO,CAAC,KAAK,CAAC,UAAU,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC3C,CAAC;qBAAM,CAAC;oBACN,MAAM,KAAK,CAAC;gBACd,CAAC;YACH,CAAC;QACH,CAAC;QAED,8CAA8C;QAC9C,IAAA,qBAAU,GAAE,CAAC;QAEb,wCAAwC;QACxC,MAAM,WAAW,GACf,MAAM,CAAC,OAAO,CAAC,QAAQ,GAAG,CAAC;YAC3B,MAAM,CAAC,OAAO,CAAC,YAAY,GAAG,CAAC;YAC/B,MAAM,CAAC,OAAO,CAAC,WAAW,GAAG,CAAC;YAC9B,MAAM,CAAC,OAAO,CAAC,iBAAiB,GAAG,CAAC,CAAC;QACvC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,kCAAoB,EAAE,CAAC;YAC1C,OAAO,CAAC,KAAK,CAAC,UAAU,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,IAAI,KAAK,YAAY,mCAAqB,EAAE,CAAC;YAC3C,OAAO,CAAC,KAAK,CAAC,UAAU,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,IAAI,KAAK,YAAY,6BAAe,EAAE,CAAC;YACrC,OAAO,CAAC,KAAK,CAAC,UAAU,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACtF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,iEAAiE;AAEjE,OAAO;KACJ,OAAO,CAAC,UAAU,CAAC;KACnB,WAAW,CAAC,4BAA4B,CAAC;KACzC,QAAQ,CAAC,OAAO,EAAE,uCAAuC,CAAC;KAC1D,MAAM,CAAC,KAAK,EAAE,GAAW,EAAE,EAAE;IAC5B,MAAM,IAAA,6BAAe,EAAC,GAAG,CAAC,CAAC;AAC7B,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,YAAY,CAAC;KACrB,WAAW,CAAC,gCAAgC,CAAC;KAC7C,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,IAAA,+BAAiB,GAAE,CAAC;AAC5B,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,+BAA+B,CAAC;KAC5C,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,IAAA,2BAAa,GAAE,CAAC;AACxB,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate a machine ID from hostname + username + platform.
|
|
3
|
+
*/
|
|
4
|
+
export declare function getMachineId(): string;
|
|
5
|
+
/**
|
|
6
|
+
* Activate a license key.
|
|
7
|
+
*/
|
|
8
|
+
export declare function activateCommand(key: string): Promise<void>;
|
|
9
|
+
/**
|
|
10
|
+
* Deactivate the current license.
|
|
11
|
+
*/
|
|
12
|
+
export declare function deactivateCommand(): Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* Show current license status.
|
|
15
|
+
*/
|
|
16
|
+
export declare function statusCommand(): Promise<void>;
|
|
17
|
+
//# sourceMappingURL=commands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/license/commands.ts"],"names":[],"mappings":"AAmBA;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAGrC;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwChE;AAED;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAmBvD;AAED;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAwBnD"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.getMachineId = getMachineId;
|
|
37
|
+
exports.activateCommand = activateCommand;
|
|
38
|
+
exports.deactivateCommand = deactivateCommand;
|
|
39
|
+
exports.statusCommand = statusCommand;
|
|
40
|
+
const crypto = __importStar(require("node:crypto"));
|
|
41
|
+
const os = __importStar(require("node:os"));
|
|
42
|
+
const validator_js_1 = require("./validator.js");
|
|
43
|
+
const storage_js_1 = require("./storage.js");
|
|
44
|
+
const usage_js_1 = require("./usage.js");
|
|
45
|
+
const http_js_1 = require("./http.js");
|
|
46
|
+
const API_BASE = 'https://license.project-shield.dev/api/v1';
|
|
47
|
+
const colors = {
|
|
48
|
+
red: (s) => `\x1b[31m${s}\x1b[0m`,
|
|
49
|
+
green: (s) => `\x1b[32m${s}\x1b[0m`,
|
|
50
|
+
yellow: (s) => `\x1b[33m${s}\x1b[0m`,
|
|
51
|
+
cyan: (s) => `\x1b[36m${s}\x1b[0m`,
|
|
52
|
+
bold: (s) => `\x1b[1m${s}\x1b[0m`,
|
|
53
|
+
dim: (s) => `\x1b[2m${s}\x1b[0m`,
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Generate a machine ID from hostname + username + platform.
|
|
57
|
+
*/
|
|
58
|
+
function getMachineId() {
|
|
59
|
+
const raw = `${os.hostname()}${os.userInfo().username}${process.platform}`;
|
|
60
|
+
return crypto.createHash('sha256').update(raw).digest('hex').substring(0, 16);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Activate a license key.
|
|
64
|
+
*/
|
|
65
|
+
async function activateCommand(key) {
|
|
66
|
+
// 1. Key format validation
|
|
67
|
+
if (!(0, validator_js_1.isValidKeyFormat)(key)) {
|
|
68
|
+
console.error(colors.red('Invalid license key format.'));
|
|
69
|
+
console.error(colors.dim('Expected: PSH-XXXX-XXXX-XXXX-XXXX'));
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
// 2. Server activation
|
|
73
|
+
const machineId = getMachineId();
|
|
74
|
+
try {
|
|
75
|
+
const response = await (0, http_js_1.postJSON)(`${API_BASE}/activate`, {
|
|
76
|
+
key,
|
|
77
|
+
machineId,
|
|
78
|
+
});
|
|
79
|
+
if (response.success && response.license) {
|
|
80
|
+
// 3. Save license file
|
|
81
|
+
const now = new Date();
|
|
82
|
+
const validUntil = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000);
|
|
83
|
+
(0, storage_js_1.writeLicenseFile)({
|
|
84
|
+
cache: {
|
|
85
|
+
license: response.license,
|
|
86
|
+
validatedAt: now.toISOString(),
|
|
87
|
+
validUntil: validUntil.toISOString(),
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
console.log(colors.green('License activated successfully!'));
|
|
91
|
+
console.log(` Tier: ${colors.bold(response.license.tier.toUpperCase())}`);
|
|
92
|
+
console.log(` Email: ${response.license.email}`);
|
|
93
|
+
console.log(` Expires: ${response.license.expiresAt}`);
|
|
94
|
+
console.log(` Scans/month: ${response.license.maxScansPerMonth}`);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
console.error(colors.red(`Activation failed: ${response.error ?? 'Unknown error'}`));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
console.error(colors.red('Could not reach license server.'));
|
|
102
|
+
console.error(colors.dim(err instanceof Error ? err.message : String(err)));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Deactivate the current license.
|
|
107
|
+
*/
|
|
108
|
+
async function deactivateCommand() {
|
|
109
|
+
const file = (0, storage_js_1.readLicenseFile)();
|
|
110
|
+
if (!file) {
|
|
111
|
+
console.log(colors.yellow('No active license found.'));
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const machineId = getMachineId();
|
|
115
|
+
try {
|
|
116
|
+
await (0, http_js_1.postJSON)(`${API_BASE}/deactivate`, {
|
|
117
|
+
key: file.cache.license.key,
|
|
118
|
+
machineId,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
// Server unreachable — still remove local license
|
|
123
|
+
}
|
|
124
|
+
(0, storage_js_1.deleteLicenseFile)();
|
|
125
|
+
console.log(colors.green('License deactivated. Reverted to Free tier.'));
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Show current license status.
|
|
129
|
+
*/
|
|
130
|
+
async function statusCommand() {
|
|
131
|
+
const tier = await (0, validator_js_1.validateLicense)();
|
|
132
|
+
const monthKey = (0, usage_js_1.getCurrentMonthKey)();
|
|
133
|
+
const usage = (0, usage_js_1.getUsageForMonth)(monthKey);
|
|
134
|
+
const file = (0, storage_js_1.readLicenseFile)();
|
|
135
|
+
console.log('');
|
|
136
|
+
console.log(colors.bold('Project Shield — License Status'));
|
|
137
|
+
console.log('');
|
|
138
|
+
console.log(` Tier: ${tier.isPro ? colors.green('Pro') : 'Free'}`);
|
|
139
|
+
console.log(` Scans: ${usage.scanCount}/${tier.maxScans} this month (${tier.scansRemaining} remaining)`);
|
|
140
|
+
console.log(` Source: ${tier.source === 'license' ? 'License key' : 'Default (no key)'}`);
|
|
141
|
+
if (file) {
|
|
142
|
+
const cache = file.cache;
|
|
143
|
+
console.log(` Key: ${cache.license.key.substring(0, 8)}...`);
|
|
144
|
+
console.log(` Email: ${cache.license.email}`);
|
|
145
|
+
console.log(` Expires: ${cache.license.expiresAt}`);
|
|
146
|
+
console.log(` Cache: Valid until ${cache.validUntil}`);
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
console.log('');
|
|
150
|
+
console.log(colors.dim(' Activate a Pro license: project-shield activate PSH-XXXX-XXXX-XXXX-XXXX'));
|
|
151
|
+
}
|
|
152
|
+
console.log('');
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/license/commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { TierStatus, FeatureGate } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Determine feature access based on tier status.
|
|
4
|
+
*
|
|
5
|
+
* | Feature | Free | Pro |
|
|
6
|
+
* |-------------------|-------|------|
|
|
7
|
+
* | evidence | false | true |
|
|
8
|
+
* | piiDetails | false | true |
|
|
9
|
+
* | cleanBadge | false | true |
|
|
10
|
+
* | fullFixit | false | true |
|
|
11
|
+
* | sealUUID | false | true |
|
|
12
|
+
*/
|
|
13
|
+
export declare function getFeatureGate(tier: TierStatus): FeatureGate;
|
|
14
|
+
//# sourceMappingURL=gate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../../src/license/gate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE1D;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,WAAW,CAoB5D"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getFeatureGate = getFeatureGate;
|
|
4
|
+
/**
|
|
5
|
+
* Determine feature access based on tier status.
|
|
6
|
+
*
|
|
7
|
+
* | Feature | Free | Pro |
|
|
8
|
+
* |-------------------|-------|------|
|
|
9
|
+
* | evidence | false | true |
|
|
10
|
+
* | piiDetails | false | true |
|
|
11
|
+
* | cleanBadge | false | true |
|
|
12
|
+
* | fullFixit | false | true |
|
|
13
|
+
* | sealUUID | false | true |
|
|
14
|
+
*/
|
|
15
|
+
function getFeatureGate(tier) {
|
|
16
|
+
if (tier.isPro) {
|
|
17
|
+
return {
|
|
18
|
+
isPro: true,
|
|
19
|
+
canGenerateEvidence: true,
|
|
20
|
+
canSeePiiDetails: true,
|
|
21
|
+
canSeeCleanBadge: true,
|
|
22
|
+
canSeeFullFixit: true,
|
|
23
|
+
canGenerateSealUUID: true,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
isPro: false,
|
|
28
|
+
canGenerateEvidence: false,
|
|
29
|
+
canSeePiiDetails: false,
|
|
30
|
+
canSeeCleanBadge: false,
|
|
31
|
+
canSeeFullFixit: false,
|
|
32
|
+
canGenerateSealUUID: false,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate.js","sourceRoot":"","sources":["../../src/license/gate.ts"],"names":[],"mappings":";;AAaA,wCAoBC;AA/BD;;;;;;;;;;GAUG;AACH,SAAgB,cAAc,CAAC,IAAgB;IAC7C,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,OAAO;YACL,KAAK,EAAE,IAAI;YACX,mBAAmB,EAAE,IAAI;YACzB,gBAAgB,EAAE,IAAI;YACtB,gBAAgB,EAAE,IAAI;YACtB,eAAe,EAAE,IAAI;YACrB,mBAAmB,EAAE,IAAI;SAC1B,CAAC;IACJ,CAAC;IAED,OAAO;QACL,KAAK,EAAE,KAAK;QACZ,mBAAmB,EAAE,KAAK;QAC1B,gBAAgB,EAAE,KAAK;QACvB,gBAAgB,EAAE,KAAK;QACvB,eAAe,EAAE,KAAK;QACtB,mBAAmB,EAAE,KAAK;KAC3B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/license/http.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CA+CrE"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.postJSON = postJSON;
|
|
37
|
+
const https = __importStar(require("node:https"));
|
|
38
|
+
const http = __importStar(require("node:http"));
|
|
39
|
+
const TIMEOUT_MS = 5000;
|
|
40
|
+
/**
|
|
41
|
+
* POST JSON to a URL and parse the JSON response.
|
|
42
|
+
* Uses node:https (no external dependencies).
|
|
43
|
+
* Timeout: 5 seconds.
|
|
44
|
+
*/
|
|
45
|
+
function postJSON(url, body) {
|
|
46
|
+
return new Promise((resolve, reject) => {
|
|
47
|
+
const data = JSON.stringify(body);
|
|
48
|
+
const parsed = new URL(url);
|
|
49
|
+
const isHttps = parsed.protocol === 'https:';
|
|
50
|
+
const options = {
|
|
51
|
+
hostname: parsed.hostname,
|
|
52
|
+
port: parsed.port || (isHttps ? 443 : 80),
|
|
53
|
+
path: parsed.pathname + parsed.search,
|
|
54
|
+
method: 'POST',
|
|
55
|
+
headers: {
|
|
56
|
+
'Content-Type': 'application/json',
|
|
57
|
+
'Content-Length': Buffer.byteLength(data),
|
|
58
|
+
'User-Agent': 'project-shield-cli/1.0.0',
|
|
59
|
+
},
|
|
60
|
+
timeout: TIMEOUT_MS,
|
|
61
|
+
};
|
|
62
|
+
const transport = isHttps ? https : http;
|
|
63
|
+
const req = transport.request(options, (res) => {
|
|
64
|
+
let responseBody = '';
|
|
65
|
+
res.setEncoding('utf-8');
|
|
66
|
+
res.on('data', (chunk) => {
|
|
67
|
+
responseBody += chunk;
|
|
68
|
+
});
|
|
69
|
+
res.on('end', () => {
|
|
70
|
+
try {
|
|
71
|
+
resolve(JSON.parse(responseBody));
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
reject(new Error(`Invalid JSON response: ${responseBody.substring(0, 200)}`));
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
req.on('timeout', () => {
|
|
79
|
+
req.destroy();
|
|
80
|
+
reject(new Error('Request timed out'));
|
|
81
|
+
});
|
|
82
|
+
req.on('error', (err) => {
|
|
83
|
+
reject(err);
|
|
84
|
+
});
|
|
85
|
+
req.write(data);
|
|
86
|
+
req.end();
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/license/http.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUA,4BA+CC;AAzDD,kDAAoC;AACpC,gDAAkC;AAElC,MAAM,UAAU,GAAG,IAAI,CAAC;AAExB;;;;GAIG;AACH,SAAgB,QAAQ,CAAC,GAAW,EAAE,IAAa;IACjD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC;QAE7C,MAAM,OAAO,GAAyB;YACpC,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACzC,IAAI,EAAE,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM;YACrC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,gBAAgB,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;gBACzC,YAAY,EAAE,0BAA0B;aACzC;YACD,OAAO,EAAE,UAAU;SACpB,CAAC;QAEF,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;QACzC,MAAM,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YAC7C,IAAI,YAAY,GAAG,EAAE,CAAC;YACtB,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;YACzB,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;gBAC/B,YAAY,IAAI,KAAK,CAAC;YACxB,CAAC,CAAC,CAAC;YACH,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;gBACjB,IAAI,CAAC;oBACH,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;gBACpC,CAAC;gBAAC,MAAM,CAAC;oBACP,MAAM,CAAC,IAAI,KAAK,CAAC,0BAA0B,YAAY,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;gBAChF,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;YACrB,GAAG,CAAC,OAAO,EAAE,CAAC;YACd,MAAM,CAAC,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;YAC7B,MAAM,CAAC,GAAG,CAAC,CAAC;QACd,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAChB,GAAG,CAAC,GAAG,EAAE,CAAC;IACZ,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { validateLicense, isValidKeyFormat, isCacheValid, isInGracePeriod } from './validator.js';
|
|
2
|
+
export { canScan, recordScan, getCurrentMonthKey, getUsageForMonth } from './usage.js';
|
|
3
|
+
export { getFeatureGate } from './gate.js';
|
|
4
|
+
export { activateCommand, deactivateCommand, statusCommand } from './commands.js';
|
|
5
|
+
export type { TierStatus, FeatureGate, LicenseInfo, LicenseCache, UsageData } from './types.js';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/license/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAClG,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACvF,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAClF,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.statusCommand = exports.deactivateCommand = exports.activateCommand = exports.getFeatureGate = exports.getUsageForMonth = exports.getCurrentMonthKey = exports.recordScan = exports.canScan = exports.isInGracePeriod = exports.isCacheValid = exports.isValidKeyFormat = exports.validateLicense = void 0;
|
|
4
|
+
var validator_js_1 = require("./validator.js");
|
|
5
|
+
Object.defineProperty(exports, "validateLicense", { enumerable: true, get: function () { return validator_js_1.validateLicense; } });
|
|
6
|
+
Object.defineProperty(exports, "isValidKeyFormat", { enumerable: true, get: function () { return validator_js_1.isValidKeyFormat; } });
|
|
7
|
+
Object.defineProperty(exports, "isCacheValid", { enumerable: true, get: function () { return validator_js_1.isCacheValid; } });
|
|
8
|
+
Object.defineProperty(exports, "isInGracePeriod", { enumerable: true, get: function () { return validator_js_1.isInGracePeriod; } });
|
|
9
|
+
var usage_js_1 = require("./usage.js");
|
|
10
|
+
Object.defineProperty(exports, "canScan", { enumerable: true, get: function () { return usage_js_1.canScan; } });
|
|
11
|
+
Object.defineProperty(exports, "recordScan", { enumerable: true, get: function () { return usage_js_1.recordScan; } });
|
|
12
|
+
Object.defineProperty(exports, "getCurrentMonthKey", { enumerable: true, get: function () { return usage_js_1.getCurrentMonthKey; } });
|
|
13
|
+
Object.defineProperty(exports, "getUsageForMonth", { enumerable: true, get: function () { return usage_js_1.getUsageForMonth; } });
|
|
14
|
+
var gate_js_1 = require("./gate.js");
|
|
15
|
+
Object.defineProperty(exports, "getFeatureGate", { enumerable: true, get: function () { return gate_js_1.getFeatureGate; } });
|
|
16
|
+
var commands_js_1 = require("./commands.js");
|
|
17
|
+
Object.defineProperty(exports, "activateCommand", { enumerable: true, get: function () { return commands_js_1.activateCommand; } });
|
|
18
|
+
Object.defineProperty(exports, "deactivateCommand", { enumerable: true, get: function () { return commands_js_1.deactivateCommand; } });
|
|
19
|
+
Object.defineProperty(exports, "statusCommand", { enumerable: true, get: function () { return commands_js_1.statusCommand; } });
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/license/index.ts"],"names":[],"mappings":";;;AAAA,+CAAkG;AAAzF,+GAAA,eAAe,OAAA;AAAE,gHAAA,gBAAgB,OAAA;AAAE,4GAAA,YAAY,OAAA;AAAE,+GAAA,eAAe,OAAA;AACzE,uCAAuF;AAA9E,mGAAA,OAAO,OAAA;AAAE,sGAAA,UAAU,OAAA;AAAE,8GAAA,kBAAkB,OAAA;AAAE,4GAAA,gBAAgB,OAAA;AAClE,qCAA2C;AAAlC,yGAAA,cAAc,OAAA;AACvB,6CAAkF;AAAzE,8GAAA,eAAe,OAAA;AAAE,gHAAA,iBAAiB,OAAA;AAAE,4GAAA,aAAa,OAAA"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { LicenseFile, UsageFile } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Get the config directory path.
|
|
4
|
+
* Uses PROJECT_SHIELD_CONFIG_DIR env var for testing, otherwise ~/.project-shield/
|
|
5
|
+
*/
|
|
6
|
+
export declare function getConfigDir(): string;
|
|
7
|
+
/**
|
|
8
|
+
* Ensure the config directory exists.
|
|
9
|
+
*/
|
|
10
|
+
export declare function ensureConfigDir(): void;
|
|
11
|
+
/**
|
|
12
|
+
* Read the license file. Returns null if not found or corrupted.
|
|
13
|
+
*/
|
|
14
|
+
export declare function readLicenseFile(): LicenseFile | null;
|
|
15
|
+
/**
|
|
16
|
+
* Write the license file.
|
|
17
|
+
*/
|
|
18
|
+
export declare function writeLicenseFile(data: LicenseFile): void;
|
|
19
|
+
/**
|
|
20
|
+
* Delete the license file.
|
|
21
|
+
*/
|
|
22
|
+
export declare function deleteLicenseFile(): void;
|
|
23
|
+
/**
|
|
24
|
+
* Read the usage file. Returns default if not found or corrupted.
|
|
25
|
+
*/
|
|
26
|
+
export declare function readUsageFile(): UsageFile;
|
|
27
|
+
/**
|
|
28
|
+
* Write the usage file.
|
|
29
|
+
*/
|
|
30
|
+
export declare function writeUsageFile(data: UsageFile): void;
|
|
31
|
+
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/license/storage.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAIzD;;;GAGG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAKtC;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,WAAW,GAAG,IAAI,CAcpD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAIxD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAKxC;AAcD;;GAEG;AACH,wBAAgB,aAAa,IAAI,SAAS,CAazC;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAIpD"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.getConfigDir = getConfigDir;
|
|
37
|
+
exports.ensureConfigDir = ensureConfigDir;
|
|
38
|
+
exports.readLicenseFile = readLicenseFile;
|
|
39
|
+
exports.writeLicenseFile = writeLicenseFile;
|
|
40
|
+
exports.deleteLicenseFile = deleteLicenseFile;
|
|
41
|
+
exports.readUsageFile = readUsageFile;
|
|
42
|
+
exports.writeUsageFile = writeUsageFile;
|
|
43
|
+
const fs = __importStar(require("node:fs"));
|
|
44
|
+
const path = __importStar(require("node:path"));
|
|
45
|
+
const os = __importStar(require("node:os"));
|
|
46
|
+
const DIR_NAME = '.project-shield';
|
|
47
|
+
/**
|
|
48
|
+
* Get the config directory path.
|
|
49
|
+
* Uses PROJECT_SHIELD_CONFIG_DIR env var for testing, otherwise ~/.project-shield/
|
|
50
|
+
*/
|
|
51
|
+
function getConfigDir() {
|
|
52
|
+
return process.env.PROJECT_SHIELD_CONFIG_DIR ?? path.join(os.homedir(), DIR_NAME);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Ensure the config directory exists.
|
|
56
|
+
*/
|
|
57
|
+
function ensureConfigDir() {
|
|
58
|
+
const dir = getConfigDir();
|
|
59
|
+
if (!fs.existsSync(dir)) {
|
|
60
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Read the license file. Returns null if not found or corrupted.
|
|
65
|
+
*/
|
|
66
|
+
function readLicenseFile() {
|
|
67
|
+
try {
|
|
68
|
+
const filePath = path.join(getConfigDir(), 'license.json');
|
|
69
|
+
if (!fs.existsSync(filePath))
|
|
70
|
+
return null;
|
|
71
|
+
const raw = fs.readFileSync(filePath, 'utf-8');
|
|
72
|
+
const data = JSON.parse(raw);
|
|
73
|
+
// Basic shape validation
|
|
74
|
+
if (!data.cache?.license?.key || !data.cache?.validatedAt || !data.cache?.validUntil) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
return data;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Write the license file.
|
|
85
|
+
*/
|
|
86
|
+
function writeLicenseFile(data) {
|
|
87
|
+
ensureConfigDir();
|
|
88
|
+
const filePath = path.join(getConfigDir(), 'license.json');
|
|
89
|
+
fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf-8');
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Delete the license file.
|
|
93
|
+
*/
|
|
94
|
+
function deleteLicenseFile() {
|
|
95
|
+
const filePath = path.join(getConfigDir(), 'license.json');
|
|
96
|
+
if (fs.existsSync(filePath)) {
|
|
97
|
+
fs.unlinkSync(filePath);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
function defaultUsage() {
|
|
101
|
+
const now = new Date();
|
|
102
|
+
const monthKey = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}`;
|
|
103
|
+
return {
|
|
104
|
+
usage: {
|
|
105
|
+
monthKey,
|
|
106
|
+
scanCount: 0,
|
|
107
|
+
lastScanAt: '',
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Read the usage file. Returns default if not found or corrupted.
|
|
113
|
+
*/
|
|
114
|
+
function readUsageFile() {
|
|
115
|
+
try {
|
|
116
|
+
const filePath = path.join(getConfigDir(), 'usage.json');
|
|
117
|
+
if (!fs.existsSync(filePath))
|
|
118
|
+
return defaultUsage();
|
|
119
|
+
const raw = fs.readFileSync(filePath, 'utf-8');
|
|
120
|
+
const data = JSON.parse(raw);
|
|
121
|
+
if (!data.usage?.monthKey || typeof data.usage?.scanCount !== 'number') {
|
|
122
|
+
return defaultUsage();
|
|
123
|
+
}
|
|
124
|
+
return data;
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
return defaultUsage();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Write the usage file.
|
|
132
|
+
*/
|
|
133
|
+
function writeUsageFile(data) {
|
|
134
|
+
ensureConfigDir();
|
|
135
|
+
const filePath = path.join(getConfigDir(), 'usage.json');
|
|
136
|
+
fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf-8');
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/license/storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export interface LicenseInfo {
|
|
2
|
+
key: string;
|
|
3
|
+
tier: 'free' | 'pro';
|
|
4
|
+
email: string;
|
|
5
|
+
activatedAt: string;
|
|
6
|
+
expiresAt: string;
|
|
7
|
+
maxScansPerMonth: number;
|
|
8
|
+
}
|
|
9
|
+
export interface LicenseCache {
|
|
10
|
+
license: LicenseInfo;
|
|
11
|
+
validatedAt: string;
|
|
12
|
+
validUntil: string;
|
|
13
|
+
}
|
|
14
|
+
export interface LicenseFile {
|
|
15
|
+
cache: LicenseCache;
|
|
16
|
+
}
|
|
17
|
+
export interface UsageData {
|
|
18
|
+
monthKey: string;
|
|
19
|
+
scanCount: number;
|
|
20
|
+
lastScanAt: string;
|
|
21
|
+
}
|
|
22
|
+
export interface UsageFile {
|
|
23
|
+
usage: UsageData;
|
|
24
|
+
}
|
|
25
|
+
export type TierStatus = {
|
|
26
|
+
tier: 'free' | 'pro';
|
|
27
|
+
isPro: boolean;
|
|
28
|
+
scansRemaining: number;
|
|
29
|
+
scansUsed: number;
|
|
30
|
+
maxScans: number;
|
|
31
|
+
source: 'license' | 'default';
|
|
32
|
+
};
|
|
33
|
+
export interface FeatureGate {
|
|
34
|
+
isPro: boolean;
|
|
35
|
+
canGenerateEvidence: boolean;
|
|
36
|
+
canSeePiiDetails: boolean;
|
|
37
|
+
canSeeCleanBadge: boolean;
|
|
38
|
+
canSeeFullFixit: boolean;
|
|
39
|
+
canGenerateSealUUID: boolean;
|
|
40
|
+
}
|
|
41
|
+
export interface ValidateResponse {
|
|
42
|
+
valid: boolean;
|
|
43
|
+
license?: LicenseInfo;
|
|
44
|
+
error?: string;
|
|
45
|
+
}
|
|
46
|
+
export interface ActivateResponse {
|
|
47
|
+
success: boolean;
|
|
48
|
+
license?: LicenseInfo;
|
|
49
|
+
error?: string;
|
|
50
|
+
}
|
|
51
|
+
export interface DeactivateResponse {
|
|
52
|
+
success: boolean;
|
|
53
|
+
error?: string;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/license/types.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,WAAW,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,YAAY,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,SAAS,CAAC;CAClB;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;IACrB,KAAK,EAAE,OAAO,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,SAAS,GAAG,SAAS,CAAC;CAC/B,CAAC;AAEF,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,OAAO,CAAC;IACf,mBAAmB,EAAE,OAAO,CAAC;IAC7B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,eAAe,EAAE,OAAO,CAAC;IACzB,mBAAmB,EAAE,OAAO,CAAC;CAC9B;AAID,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/license/types.ts"],"names":[],"mappings":";AAAA,gEAAgE"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { UsageData, TierStatus } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Get current month key in "YYYY-MM" format.
|
|
4
|
+
*/
|
|
5
|
+
export declare function getCurrentMonthKey(): string;
|
|
6
|
+
/**
|
|
7
|
+
* Get usage data for a given month. Resets if month changed.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getUsageForMonth(monthKey?: string): UsageData;
|
|
10
|
+
/**
|
|
11
|
+
* Record a scan. Increments count for current month.
|
|
12
|
+
*/
|
|
13
|
+
export declare function recordScan(): void;
|
|
14
|
+
/**
|
|
15
|
+
* Check if a scan is allowed based on tier limits.
|
|
16
|
+
* free: 5/month, pro: 50/month
|
|
17
|
+
*/
|
|
18
|
+
export declare function canScan(tier: TierStatus): {
|
|
19
|
+
allowed: boolean;
|
|
20
|
+
reason?: string;
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=usage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../../src/license/usage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExD;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAG3C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAc7D;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,IAAI,CAWjC;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAY/E"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getCurrentMonthKey = getCurrentMonthKey;
|
|
4
|
+
exports.getUsageForMonth = getUsageForMonth;
|
|
5
|
+
exports.recordScan = recordScan;
|
|
6
|
+
exports.canScan = canScan;
|
|
7
|
+
const storage_js_1 = require("./storage.js");
|
|
8
|
+
/**
|
|
9
|
+
* Get current month key in "YYYY-MM" format.
|
|
10
|
+
*/
|
|
11
|
+
function getCurrentMonthKey() {
|
|
12
|
+
const now = new Date();
|
|
13
|
+
return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}`;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Get usage data for a given month. Resets if month changed.
|
|
17
|
+
*/
|
|
18
|
+
function getUsageForMonth(monthKey) {
|
|
19
|
+
const key = monthKey ?? getCurrentMonthKey();
|
|
20
|
+
const file = (0, storage_js_1.readUsageFile)();
|
|
21
|
+
// Month rollover → reset
|
|
22
|
+
if (file.usage.monthKey !== key) {
|
|
23
|
+
return {
|
|
24
|
+
monthKey: key,
|
|
25
|
+
scanCount: 0,
|
|
26
|
+
lastScanAt: '',
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
return file.usage;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Record a scan. Increments count for current month.
|
|
33
|
+
*/
|
|
34
|
+
function recordScan() {
|
|
35
|
+
const monthKey = getCurrentMonthKey();
|
|
36
|
+
const current = getUsageForMonth(monthKey);
|
|
37
|
+
(0, storage_js_1.writeUsageFile)({
|
|
38
|
+
usage: {
|
|
39
|
+
monthKey,
|
|
40
|
+
scanCount: current.scanCount + 1,
|
|
41
|
+
lastScanAt: new Date().toISOString(),
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Check if a scan is allowed based on tier limits.
|
|
47
|
+
* free: 5/month, pro: 50/month
|
|
48
|
+
*/
|
|
49
|
+
function canScan(tier) {
|
|
50
|
+
if (tier.scansRemaining <= 0) {
|
|
51
|
+
return {
|
|
52
|
+
allowed: false,
|
|
53
|
+
reason: `Monthly scan limit reached (${tier.maxScans}/${tier.maxScans}). ${tier.isPro
|
|
54
|
+
? 'Your Pro plan allows 50 scans/month. Resets next month.'
|
|
55
|
+
: 'Upgrade to Pro for 50 scans/month: https://project-shield.dev/pro'}`,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
return { allowed: true };
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=usage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage.js","sourceRoot":"","sources":["../../src/license/usage.ts"],"names":[],"mappings":";;AAMA,gDAGC;AAKD,4CAcC;AAKD,gCAWC;AAMD,0BAYC;AA9DD,6CAA6D;AAG7D;;GAEG;AACH,SAAgB,kBAAkB;IAChC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,OAAO,GAAG,GAAG,CAAC,WAAW,EAAE,IAAI,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;AAC/E,CAAC;AAED;;GAEG;AACH,SAAgB,gBAAgB,CAAC,QAAiB;IAChD,MAAM,GAAG,GAAG,QAAQ,IAAI,kBAAkB,EAAE,CAAC;IAC7C,MAAM,IAAI,GAAG,IAAA,0BAAa,GAAE,CAAC;IAE7B,yBAAyB;IACzB,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,KAAK,GAAG,EAAE,CAAC;QAChC,OAAO;YACL,QAAQ,EAAE,GAAG;YACb,SAAS,EAAE,CAAC;YACZ,UAAU,EAAE,EAAE;SACf,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC,KAAK,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,SAAgB,UAAU;IACxB,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAC;IACtC,MAAM,OAAO,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAE3C,IAAA,2BAAc,EAAC;QACb,KAAK,EAAE;YACL,QAAQ;YACR,SAAS,EAAE,OAAO,CAAC,SAAS,GAAG,CAAC;YAChC,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACrC;KACF,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,SAAgB,OAAO,CAAC,IAAgB;IACtC,IAAI,IAAI,CAAC,cAAc,IAAI,CAAC,EAAE,CAAC;QAC7B,OAAO;YACL,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,+BAA+B,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,MACnE,IAAI,CAAC,KAAK;gBACR,CAAC,CAAC,yDAAyD;gBAC3D,CAAC,CAAC,mEACN,EAAE;SACH,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC3B,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { LicenseCache, TierStatus, ValidateResponse } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Validate key format: PSH-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}
|
|
4
|
+
*/
|
|
5
|
+
export declare function isValidKeyFormat(key: string): boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Validate license with server.
|
|
8
|
+
*/
|
|
9
|
+
export declare function validateWithServer(key: string): Promise<ValidateResponse>;
|
|
10
|
+
/**
|
|
11
|
+
* Check if cache is within the 7-day validity window.
|
|
12
|
+
*/
|
|
13
|
+
export declare function isCacheValid(cache: LicenseCache): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Check if still within the grace period (3 extra days after cache expires).
|
|
16
|
+
*/
|
|
17
|
+
export declare function isInGracePeriod(cache: LicenseCache): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Main license validation flow:
|
|
20
|
+
* 1. No license.json → free (default)
|
|
21
|
+
* 2. Cache valid (7 days) → return cached tier
|
|
22
|
+
* 3. Cache expired → try server re-validation
|
|
23
|
+
* 4. Server success → update cache, return tier
|
|
24
|
+
* 5. Server fail + grace period → cached tier + warning
|
|
25
|
+
* 6. Grace expired → downgrade to free
|
|
26
|
+
*/
|
|
27
|
+
export declare function validateLicense(): Promise<TierStatus>;
|
|
28
|
+
//# sourceMappingURL=validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/license/validator.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAO7E;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAG/E;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAIzD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAK5D;AAkBD;;;;;;;;GAQG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,UAAU,CAAC,CA6C3D"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isValidKeyFormat = isValidKeyFormat;
|
|
4
|
+
exports.validateWithServer = validateWithServer;
|
|
5
|
+
exports.isCacheValid = isCacheValid;
|
|
6
|
+
exports.isInGracePeriod = isInGracePeriod;
|
|
7
|
+
exports.validateLicense = validateLicense;
|
|
8
|
+
const storage_js_1 = require("./storage.js");
|
|
9
|
+
const usage_js_1 = require("./usage.js");
|
|
10
|
+
const http_js_1 = require("./http.js");
|
|
11
|
+
const API_BASE = 'https://license.project-shield.dev/api/v1';
|
|
12
|
+
const KEY_PATTERN = /^PSH-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}$/;
|
|
13
|
+
const CACHE_DAYS = 7;
|
|
14
|
+
const GRACE_DAYS = 3;
|
|
15
|
+
/**
|
|
16
|
+
* Validate key format: PSH-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}
|
|
17
|
+
*/
|
|
18
|
+
function isValidKeyFormat(key) {
|
|
19
|
+
return KEY_PATTERN.test(key);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Validate license with server.
|
|
23
|
+
*/
|
|
24
|
+
async function validateWithServer(key) {
|
|
25
|
+
const response = await (0, http_js_1.postJSON)(`${API_BASE}/validate`, { key });
|
|
26
|
+
return response;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Check if cache is within the 7-day validity window.
|
|
30
|
+
*/
|
|
31
|
+
function isCacheValid(cache) {
|
|
32
|
+
const now = Date.now();
|
|
33
|
+
const validUntil = new Date(cache.validUntil).getTime();
|
|
34
|
+
return now < validUntil;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Check if still within the grace period (3 extra days after cache expires).
|
|
38
|
+
*/
|
|
39
|
+
function isInGracePeriod(cache) {
|
|
40
|
+
const now = Date.now();
|
|
41
|
+
const validUntil = new Date(cache.validUntil).getTime();
|
|
42
|
+
const graceEnd = validUntil + GRACE_DAYS * 24 * 60 * 60 * 1000;
|
|
43
|
+
return now >= validUntil && now < graceEnd;
|
|
44
|
+
}
|
|
45
|
+
function makeTierStatus(tier, maxScans, source) {
|
|
46
|
+
const usage = (0, usage_js_1.getUsageForMonth)((0, usage_js_1.getCurrentMonthKey)());
|
|
47
|
+
return {
|
|
48
|
+
tier,
|
|
49
|
+
isPro: tier === 'pro',
|
|
50
|
+
scansRemaining: Math.max(0, maxScans - usage.scanCount),
|
|
51
|
+
scansUsed: usage.scanCount,
|
|
52
|
+
maxScans,
|
|
53
|
+
source,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Main license validation flow:
|
|
58
|
+
* 1. No license.json → free (default)
|
|
59
|
+
* 2. Cache valid (7 days) → return cached tier
|
|
60
|
+
* 3. Cache expired → try server re-validation
|
|
61
|
+
* 4. Server success → update cache, return tier
|
|
62
|
+
* 5. Server fail + grace period → cached tier + warning
|
|
63
|
+
* 6. Grace expired → downgrade to free
|
|
64
|
+
*/
|
|
65
|
+
async function validateLicense() {
|
|
66
|
+
const file = (0, storage_js_1.readLicenseFile)();
|
|
67
|
+
// 1. No license file → free
|
|
68
|
+
if (!file) {
|
|
69
|
+
return makeTierStatus('free', 5, 'default');
|
|
70
|
+
}
|
|
71
|
+
const cache = file.cache;
|
|
72
|
+
// 2. Cache valid
|
|
73
|
+
if (isCacheValid(cache)) {
|
|
74
|
+
const max = cache.license.tier === 'pro' ? 50 : 5;
|
|
75
|
+
return makeTierStatus(cache.license.tier, max, 'license');
|
|
76
|
+
}
|
|
77
|
+
// 3. Cache expired → try server
|
|
78
|
+
try {
|
|
79
|
+
const response = await validateWithServer(cache.license.key);
|
|
80
|
+
if (response.valid && response.license) {
|
|
81
|
+
// 4. Server success → update cache
|
|
82
|
+
const now = new Date();
|
|
83
|
+
const validUntil = new Date(now.getTime() + CACHE_DAYS * 24 * 60 * 60 * 1000);
|
|
84
|
+
(0, storage_js_1.writeLicenseFile)({
|
|
85
|
+
cache: {
|
|
86
|
+
license: response.license,
|
|
87
|
+
validatedAt: now.toISOString(),
|
|
88
|
+
validUntil: validUntil.toISOString(),
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
const max = response.license.tier === 'pro' ? 50 : 5;
|
|
92
|
+
return makeTierStatus(response.license.tier, max, 'license');
|
|
93
|
+
}
|
|
94
|
+
// Server says invalid → downgrade
|
|
95
|
+
return makeTierStatus('free', 5, 'default');
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
// 5. Server unreachable
|
|
99
|
+
if (isInGracePeriod(cache)) {
|
|
100
|
+
// Grace period → use cached tier with warning
|
|
101
|
+
const max = cache.license.tier === 'pro' ? 50 : 5;
|
|
102
|
+
return makeTierStatus(cache.license.tier, max, 'license');
|
|
103
|
+
}
|
|
104
|
+
// 6. Grace expired → downgrade
|
|
105
|
+
return makeTierStatus('free', 5, 'default');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/license/validator.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import type { ScanResult, ScanScore, LockStatus, SealedResult } from '../types/index.js';
|
|
2
2
|
/**
|
|
3
3
|
* Format scan results for terminal output.
|
|
4
|
+
* @param options.isPro - If false, PII section shows summary only (no file:line details).
|
|
4
5
|
*/
|
|
5
|
-
export declare function formatTerminalOutput(result: ScanResult, rulesetVersion: string, rulesetHash: string, score?: ScanScore, lockStatus?: LockStatus
|
|
6
|
+
export declare function formatTerminalOutput(result: ScanResult, rulesetVersion: string, rulesetHash: string, score?: ScanScore, lockStatus?: LockStatus, options?: {
|
|
7
|
+
isPro?: boolean;
|
|
8
|
+
}): string;
|
|
6
9
|
/**
|
|
7
10
|
* Format scan results as JSON.
|
|
11
|
+
* @param options.isPro - If false, PII array is replaced with a summary object.
|
|
8
12
|
*/
|
|
9
|
-
export declare function formatJsonOutput(result: ScanResult, score?: ScanScore, seal?: SealedResult
|
|
13
|
+
export declare function formatJsonOutput(result: ScanResult, score?: ScanScore, seal?: SealedResult, options?: {
|
|
14
|
+
isPro?: boolean;
|
|
15
|
+
}): string;
|
|
10
16
|
//# sourceMappingURL=terminal.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/output/terminal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EAKV,SAAS,EACT,UAAU,EACV,YAAY,EACb,MAAM,mBAAmB,CAAC;AAiG3B
|
|
1
|
+
{"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/output/terminal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EAKV,SAAS,EACT,UAAU,EACV,YAAY,EACb,MAAM,mBAAmB,CAAC;AAiG3B;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,UAAU,EAClB,cAAc,EAAE,MAAM,EACtB,WAAW,EAAE,MAAM,EACnB,KAAK,CAAC,EAAE,SAAS,EACjB,UAAU,CAAC,EAAE,UAAU,EACvB,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAC5B,MAAM,CAqGR;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,UAAU,EAClB,KAAK,CAAC,EAAE,SAAS,EACjB,IAAI,CAAC,EAAE,YAAY,EACnB,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAC5B,MAAM,CAmBR"}
|
package/dist/output/terminal.js
CHANGED
|
@@ -85,8 +85,9 @@ function formatInjectionFinding(finding) {
|
|
|
85
85
|
}
|
|
86
86
|
/**
|
|
87
87
|
* Format scan results for terminal output.
|
|
88
|
+
* @param options.isPro - If false, PII section shows summary only (no file:line details).
|
|
88
89
|
*/
|
|
89
|
-
function formatTerminalOutput(result, rulesetVersion, rulesetHash, score, lockStatus) {
|
|
90
|
+
function formatTerminalOutput(result, rulesetVersion, rulesetHash, score, lockStatus, options) {
|
|
90
91
|
const lines = [];
|
|
91
92
|
lines.push('');
|
|
92
93
|
lines.push(colors.bold('Project Shield v1.0.0'));
|
|
@@ -111,6 +112,13 @@ function formatTerminalOutput(result, rulesetVersion, rulesetHash, score, lockSt
|
|
|
111
112
|
if (result.pii.length === 0) {
|
|
112
113
|
lines.push(colors.green(' No PII detected.'));
|
|
113
114
|
}
|
|
115
|
+
else if (options?.isPro === false) {
|
|
116
|
+
// Free tier: summary only (no file:line details)
|
|
117
|
+
const confirmed = result.pii.filter(p => p.severity === 'confirmed').length;
|
|
118
|
+
const possible = result.pii.filter(p => p.severity === 'possible').length;
|
|
119
|
+
lines.push(` PII ${result.pii.length} finding(s) (Confirmed: ${confirmed}, Possible: ${possible})`);
|
|
120
|
+
lines.push(colors.dim(' Detailed PII locations available in Pro tier.'));
|
|
121
|
+
}
|
|
114
122
|
else {
|
|
115
123
|
for (const finding of result.pii) {
|
|
116
124
|
lines.push(formatPIIFinding(finding));
|
|
@@ -176,8 +184,9 @@ function formatTerminalOutput(result, rulesetVersion, rulesetHash, score, lockSt
|
|
|
176
184
|
}
|
|
177
185
|
/**
|
|
178
186
|
* Format scan results as JSON.
|
|
187
|
+
* @param options.isPro - If false, PII array is replaced with a summary object.
|
|
179
188
|
*/
|
|
180
|
-
function formatJsonOutput(result, score, seal) {
|
|
189
|
+
function formatJsonOutput(result, score, seal, options) {
|
|
181
190
|
const output = { ...result };
|
|
182
191
|
if (score) {
|
|
183
192
|
output.score = score;
|
|
@@ -185,6 +194,16 @@ function formatJsonOutput(result, score, seal) {
|
|
|
185
194
|
if (seal) {
|
|
186
195
|
output.seal = seal;
|
|
187
196
|
}
|
|
197
|
+
// Free tier: replace PII array with summary
|
|
198
|
+
if (options?.isPro === false) {
|
|
199
|
+
const confirmed = result.pii.filter(p => p.severity === 'confirmed').length;
|
|
200
|
+
const possible = result.pii.filter(p => p.severity === 'possible').length;
|
|
201
|
+
output.pii = {
|
|
202
|
+
count: result.pii.length,
|
|
203
|
+
confirmed,
|
|
204
|
+
possible,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
188
207
|
return JSON.stringify(output, null, 2);
|
|
189
208
|
}
|
|
190
209
|
//# sourceMappingURL=terminal.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminal.js","sourceRoot":"","sources":["../../src/output/terminal.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"terminal.js","sourceRoot":"","sources":["../../src/output/terminal.ts"],"names":[],"mappings":"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"}
|