@produtype/core 0.84.1 → 0.86.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.
|
@@ -139,6 +139,42 @@ async function detectDatabase(ctx) {
|
|
|
139
139
|
for (const hit of hits)
|
|
140
140
|
evidence.push({ type: 'dependency', value: hit });
|
|
141
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
* Laravel, whose database is named in a configuration file rather than in a package.
|
|
144
|
+
*
|
|
145
|
+
* PHP has one driver — PDO, in the runtime — so `composer.json` says nothing about
|
|
146
|
+
* which engine a project talks to, and nothing here read the place that does.
|
|
147
|
+
* Firefly III reported no data layer at all, above a `config/database.php` whose
|
|
148
|
+
* first line of substance is `'default' => env('DB_CONNECTION', 'mysql')`.
|
|
149
|
+
*
|
|
150
|
+
* Only the default is read. Laravel's file ships every driver it supports in the
|
|
151
|
+
* `connections` array whether the project uses them or not, so reading those would
|
|
152
|
+
* credit each project with four databases; the default is the one it actually falls
|
|
153
|
+
* back to when nothing is configured, which is the project's own statement.
|
|
154
|
+
*/
|
|
155
|
+
const LARAVEL_DRIVERS = {
|
|
156
|
+
mysql: 'mysql',
|
|
157
|
+
mariadb: 'mysql',
|
|
158
|
+
pgsql: 'postgres',
|
|
159
|
+
sqlite: 'sqlite',
|
|
160
|
+
sqlsrv: 'sqlserver',
|
|
161
|
+
};
|
|
162
|
+
for (const file of ctx.files.all.filter((f) => /(^|\/)config\/database\.php$/.test(f))) {
|
|
163
|
+
const text = await (0, readTextFileSafe_1.readTextFileSafe)(ctx.root, file);
|
|
164
|
+
if (!text)
|
|
165
|
+
continue;
|
|
166
|
+
const defaultLine = /^\s*'default'\s*=>.*?['"]([a-z]+)['"]/m.exec(text);
|
|
167
|
+
const driver = defaultLine ? LARAVEL_DRIVERS[defaultLine[1]] : undefined;
|
|
168
|
+
if (!driver)
|
|
169
|
+
continue;
|
|
170
|
+
databases.add(driver);
|
|
171
|
+
evidence.push({
|
|
172
|
+
type: 'snippet',
|
|
173
|
+
value: defaultLine[0].trim().slice(0, 200),
|
|
174
|
+
file,
|
|
175
|
+
line: text.slice(0, defaultLine.index).split('\n').length,
|
|
176
|
+
});
|
|
177
|
+
}
|
|
142
178
|
const dotnetHits = [
|
|
143
179
|
['postgres', ['Npgsql']],
|
|
144
180
|
['mysql', ['MySql.Data', 'Pomelo.EntityFrameworkCore.MySql']],
|
|
@@ -366,6 +366,51 @@ async function detectSecurity(ctx) {
|
|
|
366
366
|
* `CORS_ORIGIN_ALLOW_ALL`, which is what it was called before version 3.5 — is the
|
|
367
367
|
* one line that opens it.
|
|
368
368
|
*/
|
|
369
|
+
/**
|
|
370
|
+
* Laravel's answer, which is a file with a name the framework chose.
|
|
371
|
+
*
|
|
372
|
+
* `config/cors.php` is published by Laravel and read by its own middleware; a
|
|
373
|
+
* project either has it or does not. Firefly III has one whose `'allowed_origins'`
|
|
374
|
+
* is `['*']`, and the report said it had no cross-origin configuration at all —
|
|
375
|
+
* the worst direction for this check, because a project that opened itself to the
|
|
376
|
+
* whole web read as one that had not thought about it.
|
|
377
|
+
*
|
|
378
|
+
* The path is the anchor and the array is the answer: a bare `'*'` is the wide-open
|
|
379
|
+
* case, and a list of origins is one somebody chose.
|
|
380
|
+
*/
|
|
381
|
+
for (const file of source.concat(ctx.files.all).filter((f) => /(^|\/)config\/cors\.php$/.test(f))) {
|
|
382
|
+
const text = await (0, readTextFileSafe_1.readTextFileSafe)(ctx.root, file);
|
|
383
|
+
if (!text)
|
|
384
|
+
continue;
|
|
385
|
+
const origins = /'allowed_origins'\s*=>\s*\[([^\]]*)\]/.exec(text);
|
|
386
|
+
const line = origins ? text.slice(0, origins.index).split('\n').length : 1;
|
|
387
|
+
const hit = { file, line, snippet: (origins?.[0] ?? "config/cors.php").replace(/\s+/g, ' ').trim().slice(0, 200) };
|
|
388
|
+
if (!origins || /^\s*'\*'\s*,?\s*$/.test(origins[1]))
|
|
389
|
+
corsLoose.push(hit);
|
|
390
|
+
else
|
|
391
|
+
corsStrict.push(hit);
|
|
392
|
+
break;
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* ASP.NET Core's, which is a call to the framework's own builder.
|
|
396
|
+
*
|
|
397
|
+
* `AddCors()` registers the service and `UseCors()` puts it in the pipeline; both
|
|
398
|
+
* names belong to the framework. Jellyfin calls each of them and was told at `high`
|
|
399
|
+
* that it has no cross-origin configuration.
|
|
400
|
+
*
|
|
401
|
+
* Which policy it is comes from the builder: `AllowAnyOrigin()` is the wide-open
|
|
402
|
+
* one and `WithOrigins(...)` is a list somebody chose. Jellyfin has both — the
|
|
403
|
+
* first when no hosts are configured — and where both are shipped the open branch
|
|
404
|
+
* is the one worth reporting, because it is reachable.
|
|
405
|
+
*/
|
|
406
|
+
const aspNetCors = await (0, textSearch_1.searchInFiles)(ctx.root, source.filter((f) => /\.cs$/i.test(f)), [/\.\s*AddCors\s*\(/, /\.\s*UseCors\s*\(/, /\bUseCors\s*\(/, /\bAddCors\s*\(/], 5);
|
|
407
|
+
if (aspNetCors.length > 0) {
|
|
408
|
+
const anyOrigin = await (0, textSearch_1.searchInFiles)(ctx.root, source.filter((f) => /\.cs$/i.test(f)), [/AllowAnyOrigin\s*\(/], 2);
|
|
409
|
+
const chosen = await (0, textSearch_1.searchInFiles)(ctx.root, source.filter((f) => /\.cs$/i.test(f)), [/WithOrigins\s*\(/, /SetIsOriginAllowed\s*\(/], 2);
|
|
410
|
+
const target = anyOrigin.length > 0 || chosen.length === 0 ? corsLoose : corsStrict;
|
|
411
|
+
const cited = anyOrigin[0] ?? chosen[0] ?? aspNetCors[0];
|
|
412
|
+
target.push({ file: cited.file, line: cited.line, snippet: cited.snippet.trim().slice(0, 200) });
|
|
413
|
+
}
|
|
369
414
|
const django = await (0, djangoSettings_1.findDjangoSettings)(ctx);
|
|
370
415
|
if (django) {
|
|
371
416
|
const middlewareLine = django.text
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@produtype/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.86.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": {
|