@produtype/core 0.26.0 → 0.26.1
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/analyzer/detectAuth.js +25 -3
- package/package.json +1 -1
|
@@ -90,7 +90,20 @@ async function detectAuth(ctx) {
|
|
|
90
90
|
/createServerClient/,
|
|
91
91
|
/\[\.\.\.nextauth\]/i,
|
|
92
92
|
], 30);
|
|
93
|
-
|
|
93
|
+
/**
|
|
94
|
+
* `otp` as a word, not as three letters inside another one.
|
|
95
|
+
*
|
|
96
|
+
* `/otp/i` matched `VarError::NotPresent` and `PandasUseOfDotPivotOrUpdate` — N-**otp**-resent
|
|
97
|
+
* and D-**otp**-ivot — so a Rust linter was credited with two-factor authentication.
|
|
98
|
+
* Two of the three signals behind that reading were substring collisions of this kind.
|
|
99
|
+
*
|
|
100
|
+
* Word boundaries in the languages people actually write: delimited by a non-letter
|
|
101
|
+
* (`otp_secret`, `verify(otp)`), or the capital that starts a camelCase word
|
|
102
|
+
* (`verifyOtp`, `otpCode`). `pyotp` no longer matches here and does not need to: it is
|
|
103
|
+
* a dependency, and dependencies are read from the manifest above.
|
|
104
|
+
*/
|
|
105
|
+
const OTP_AS_A_WORD = /(?:^|[^a-z])t?otp(?:[^a-z]|$)|[a-z_](?:Otp|OTP|Totp|TOTP)/;
|
|
106
|
+
const twoFaSignals = await (0, textSearch_1.searchInFiles)(ctx.root, sourceFiles, [/two[_-]?factor/i, OTP_AS_A_WORD], 20);
|
|
94
107
|
const apiKeySignals = await (0, textSearch_1.searchInFiles)(ctx.root, sourceFiles, [
|
|
95
108
|
/**
|
|
96
109
|
* A key this project checks, not a key it holds.
|
|
@@ -206,8 +219,17 @@ async function detectAuth(ctx) {
|
|
|
206
219
|
const organizationSignals = strongOrganization.length > 0
|
|
207
220
|
? [...strongOrganization, ...weakOrganization]
|
|
208
221
|
: [];
|
|
209
|
-
|
|
210
|
-
|
|
222
|
+
/**
|
|
223
|
+
* `memberId` is a weak word, by this detector's own rule.
|
|
224
|
+
*
|
|
225
|
+
* It was strong enough to stand alone, and `ScopedMemberId` — a symbol table in a
|
|
226
|
+
* compiler — was read as a tenant membership. "Member" means a struct field in most
|
|
227
|
+
* languages and a person in a few; only a tenant word says which. The comment above
|
|
228
|
+
* already states the principle: a weak word never stands on its own, however many
|
|
229
|
+
* files it appears in.
|
|
230
|
+
*/
|
|
231
|
+
const strongMembership = await (0, textSearch_1.searchInFiles)(ctx.root, sourceFiles, STRONG_TENANCY, 25);
|
|
232
|
+
const weakMembership = await (0, textSearch_1.searchInFiles)(ctx.root, sourceFiles, [/memberId/i, ...WEAK_TENANCY], 25);
|
|
211
233
|
const membershipSignals = strongMembership.length > 0 ? [...strongMembership, ...weakMembership] : [];
|
|
212
234
|
const b2bSignals = await (0, textSearch_1.searchInFiles)(ctx.root, sourceFiles, [
|
|
213
235
|
/stripe/i,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@produtype/core",
|
|
3
|
-
"version": "0.26.
|
|
3
|
+
"version": "0.26.1",
|
|
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": {
|