@produtype/core 0.19.1 → 0.20.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/rules/rules.js +62 -13
- package/package.json +1 -1
package/dist/rules/rules.js
CHANGED
|
@@ -203,9 +203,24 @@ exports.rules = [
|
|
|
203
203
|
category: 'env',
|
|
204
204
|
status,
|
|
205
205
|
severity: sevForStatus(status, 'medium'),
|
|
206
|
+
/**
|
|
207
|
+
* One sentence per answer.
|
|
208
|
+
*
|
|
209
|
+
* "Environment template looks available or env usage was not detected" is two
|
|
210
|
+
* different findings sharing a line, and sixty-two of the seventy-eight
|
|
211
|
+
* repositories in the corpus were shown it: nineteen that have a template, and
|
|
212
|
+
* forty-three that read no environment variables at all. A reader cannot tell
|
|
213
|
+
* which one they are, and those call for opposite actions — one is done, the
|
|
214
|
+
* other was never asked.
|
|
215
|
+
*
|
|
216
|
+
* The status already knew. This is the same mistake the privacy check was
|
|
217
|
+
* corrected for, still being made one rule above it.
|
|
218
|
+
*/
|
|
206
219
|
description: missing
|
|
207
220
|
? 'The project reads environment variables but no .env.example was detected.'
|
|
208
|
-
:
|
|
221
|
+
: status === 'passed'
|
|
222
|
+
? 'An environment template is present alongside the variables this project reads.'
|
|
223
|
+
: 'Nothing here reads environment variables, so there is no template to check.',
|
|
209
224
|
recommendation: 'Provide a safe .env.example containing required keys and no secrets.',
|
|
210
225
|
evidence: det?.evidence ?? [],
|
|
211
226
|
});
|
|
@@ -338,7 +353,19 @@ exports.rules = [
|
|
|
338
353
|
category: 'security',
|
|
339
354
|
status,
|
|
340
355
|
severity: sevForStatus(status, 'medium'),
|
|
341
|
-
|
|
356
|
+
/**
|
|
357
|
+
* `unknown` here means the check does not apply — this detector only reads
|
|
358
|
+
* Express middleware, and a Django project has rate limiting somewhere it cannot
|
|
359
|
+
* see. Saying "no rate limiting detected" for that is reporting the analyzer's
|
|
360
|
+
* blind spot as the project's gap.
|
|
361
|
+
*/
|
|
362
|
+
description: status === 'passed'
|
|
363
|
+
? 'Rate limiting signals detected on the authentication surface.'
|
|
364
|
+
: status === 'missing'
|
|
365
|
+
? 'No auth-focused rate limiting detected.'
|
|
366
|
+
: !hasAuth
|
|
367
|
+
? 'Nothing here authenticates anybody, so there is no login surface to throttle.'
|
|
368
|
+
: 'This check reads Express middleware, and this project does not use it — any throttling it has is somewhere this cannot see.',
|
|
342
369
|
recommendation: 'Apply express-rate-limit (or equivalent) to login/register/password reset endpoints.',
|
|
343
370
|
/**
|
|
344
371
|
* The claim is about rate limiting, so the evidence is about rate limiting.
|
|
@@ -453,7 +480,9 @@ exports.rules = [
|
|
|
453
480
|
? 'Uploads look publicly exposed without auth checks.'
|
|
454
481
|
: status === 'partial'
|
|
455
482
|
? 'Uploads are exposed and some auth signals exist, review route protection.'
|
|
456
|
-
:
|
|
483
|
+
: status === 'passed'
|
|
484
|
+
? 'Upload handling was found, and none of it is publicly exposed.'
|
|
485
|
+
: 'No upload handling was found in this repository.',
|
|
457
486
|
recommendation: 'Protect upload routes with authz, validate MIME/type, and prefer private object storage.',
|
|
458
487
|
evidence: up?.evidence ?? [],
|
|
459
488
|
});
|
|
@@ -475,7 +504,13 @@ exports.rules = [
|
|
|
475
504
|
category: 'auth',
|
|
476
505
|
status,
|
|
477
506
|
severity: sevForStatus(status, 'medium'),
|
|
478
|
-
description: status === 'missing'
|
|
507
|
+
description: status === 'missing'
|
|
508
|
+
? 'No clear authentication signals detected.'
|
|
509
|
+
: status === 'unknown'
|
|
510
|
+
? 'Nothing in this repository serves requests or holds accounts, so there is nobody here to authenticate.'
|
|
511
|
+
: status === 'partial'
|
|
512
|
+
? 'Authentication signals detected, but not a complete flow.'
|
|
513
|
+
: 'Authentication signals detected.',
|
|
479
514
|
recommendation: 'Implement robust auth flow and secure credential handling.',
|
|
480
515
|
evidence: auth?.evidence ?? [],
|
|
481
516
|
});
|
|
@@ -515,7 +550,11 @@ exports.rules = [
|
|
|
515
550
|
? 'Permission-level authorization signals detected.'
|
|
516
551
|
: status === 'partial'
|
|
517
552
|
? 'Only basic role checks detected.'
|
|
518
|
-
:
|
|
553
|
+
: status === 'missing'
|
|
554
|
+
? 'No resource-level authorization signals detected.'
|
|
555
|
+
: !hasAuth
|
|
556
|
+
? 'Nothing here authenticates anybody, so there are no callers to authorize.'
|
|
557
|
+
: 'Nothing in this repository serves requests, so there are no records to guard.',
|
|
519
558
|
recommendation: 'Add policy/resource-level checks beyond coarse role gates.',
|
|
520
559
|
evidence: [...(roles?.evidence ?? []), ...(permissions?.evidence ?? []), ...(resourceLevel?.evidence ?? [])],
|
|
521
560
|
});
|
|
@@ -598,9 +637,15 @@ exports.rules = [
|
|
|
598
637
|
category: 'gdpr',
|
|
599
638
|
status,
|
|
600
639
|
severity: sevForStatus(status, 'medium'),
|
|
601
|
-
description:
|
|
640
|
+
description: status === 'missing'
|
|
602
641
|
? 'Auth/users signals found but no GDPR/privacy controls detected.'
|
|
603
|
-
:
|
|
642
|
+
: status === 'passed'
|
|
643
|
+
? 'Consent, export, erasure or retention controls detected.'
|
|
644
|
+
: hasGdpr
|
|
645
|
+
? 'Privacy controls were found, but nothing here serves requests or holds accounts for them to apply to.'
|
|
646
|
+
: !hasUserFacingSurface(analysis)
|
|
647
|
+
? 'Nothing in this repository serves requests or holds accounts, so there is no personal data flow here to check.'
|
|
648
|
+
: 'No accounts or user records were detected, so there is nothing here for these duties to attach to.',
|
|
604
649
|
recommendation: 'Implement consent, export/erasure workflows, and retention policies.',
|
|
605
650
|
evidence: [
|
|
606
651
|
...(consent?.evidence ?? []),
|
|
@@ -771,7 +816,9 @@ exports.rules = [
|
|
|
771
816
|
? 'Nothing in this repository is deployed as a running service, so how it reaches people — a registry, a store, a host — is decided outside it.'
|
|
772
817
|
: status === 'missing'
|
|
773
818
|
? 'No meaningful deployment artifacts or prod/runtime signals detected.'
|
|
774
|
-
:
|
|
819
|
+
: status === 'partial'
|
|
820
|
+
? 'Deployment artifacts detected, but the production-aware runtime settings are incomplete.'
|
|
821
|
+
: 'Deployment artifacts and production-aware runtime settings detected.',
|
|
775
822
|
/**
|
|
776
823
|
* Graceful shutdown is left out where there is no signal to catch: PHP-FPM and
|
|
777
824
|
* CGI hand each request to a worker that exits when it is done, and telling a
|
|
@@ -814,11 +861,13 @@ exports.rules = [
|
|
|
814
861
|
category: 'deployment',
|
|
815
862
|
status,
|
|
816
863
|
severity: sevForStatus(status, 'low'),
|
|
817
|
-
description:
|
|
818
|
-
? '
|
|
819
|
-
:
|
|
820
|
-
? '
|
|
821
|
-
:
|
|
864
|
+
description: status === 'passed'
|
|
865
|
+
? 'A Dockerfile and a compose file were found.'
|
|
866
|
+
: status === 'partial'
|
|
867
|
+
? 'Docker artifacts were found, but not the whole set — a Dockerfile without a compose file, or the reverse.'
|
|
868
|
+
: containerisable
|
|
869
|
+
? 'No Docker artifacts found.'
|
|
870
|
+
: 'Nothing here is deployed as a container.',
|
|
822
871
|
recommendation: containerisable ? 'Provide Dockerfile and healthchecks for reproducible deployments.' : '',
|
|
823
872
|
evidence: docker?.evidence ?? [],
|
|
824
873
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@produtype/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"description": "Deterministic CLI and library that analyzes a web application repository and reports how far it is from production-ready for the kind of product it is meant to be.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|