@futdevpro/nts-dynamo 1.15.150 → 1.15.151
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.
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"pid":
|
|
3
|
-
"startedAt": "2026-08-
|
|
4
|
-
"startedAtMs":
|
|
2
|
+
"pid": 3434,
|
|
3
|
+
"startedAt": "2026-08-22T10:06:08.665Z",
|
|
4
|
+
"startedAtMs": 1787393168665,
|
|
5
5
|
"phase": "npm-publish",
|
|
6
6
|
"pipelineComplete": false,
|
|
7
7
|
"serverRunning": false,
|
|
@@ -10,63 +10,63 @@
|
|
|
10
10
|
"steps": {
|
|
11
11
|
"validate-secrets": {
|
|
12
12
|
"status": "ok",
|
|
13
|
-
"startedAt": "2026-08-
|
|
13
|
+
"startedAt": "2026-08-22T10:06:08.682Z",
|
|
14
14
|
"logLineStart": 2,
|
|
15
15
|
"logLineEnd": 8,
|
|
16
|
-
"durationSec": 2.
|
|
16
|
+
"durationSec": 2.3
|
|
17
17
|
},
|
|
18
18
|
"discord-start": {
|
|
19
19
|
"status": "ok",
|
|
20
|
-
"startedAt": "2026-08-
|
|
20
|
+
"startedAt": "2026-08-22T10:06:11.955Z",
|
|
21
21
|
"logLineStart": 9,
|
|
22
22
|
"logLineEnd": 16,
|
|
23
23
|
"durationSec": 5
|
|
24
24
|
},
|
|
25
25
|
"pre-flight": {
|
|
26
26
|
"status": "ok",
|
|
27
|
-
"startedAt": "2026-08-
|
|
27
|
+
"startedAt": "2026-08-22T10:06:17.944Z",
|
|
28
28
|
"logLineStart": 17,
|
|
29
29
|
"logLineEnd": 19,
|
|
30
30
|
"durationSec": 2.2
|
|
31
31
|
},
|
|
32
32
|
"install": {
|
|
33
33
|
"status": "ok",
|
|
34
|
-
"startedAt": "2026-08-
|
|
34
|
+
"startedAt": "2026-08-22T10:06:21.154Z",
|
|
35
35
|
"logLineStart": 20,
|
|
36
|
-
"logLineEnd":
|
|
37
|
-
"durationSec":
|
|
36
|
+
"logLineEnd": 102,
|
|
37
|
+
"durationSec": 27.9
|
|
38
38
|
},
|
|
39
39
|
"check-dev-leftovers": {
|
|
40
40
|
"status": "ok",
|
|
41
|
-
"startedAt": "2026-08-
|
|
42
|
-
"logLineStart":
|
|
43
|
-
"logLineEnd":
|
|
44
|
-
"durationSec": 6
|
|
41
|
+
"startedAt": "2026-08-22T10:06:50.006Z",
|
|
42
|
+
"logLineStart": 103,
|
|
43
|
+
"logLineEnd": 112,
|
|
44
|
+
"durationSec": 6.6
|
|
45
45
|
},
|
|
46
46
|
"build": {
|
|
47
47
|
"status": "ok",
|
|
48
|
-
"startedAt": "2026-08-
|
|
49
|
-
"logLineStart":
|
|
50
|
-
"logLineEnd":
|
|
51
|
-
"durationSec":
|
|
48
|
+
"startedAt": "2026-08-22T10:06:57.613Z",
|
|
49
|
+
"logLineStart": 113,
|
|
50
|
+
"logLineEnd": 114,
|
|
51
|
+
"durationSec": 43.9
|
|
52
52
|
},
|
|
53
53
|
"test": {
|
|
54
54
|
"status": "ok",
|
|
55
|
-
"startedAt": "2026-08-
|
|
56
|
-
"logLineStart":
|
|
57
|
-
"logLineEnd":
|
|
58
|
-
"durationSec":
|
|
55
|
+
"startedAt": "2026-08-22T10:07:42.487Z",
|
|
56
|
+
"logLineStart": 115,
|
|
57
|
+
"logLineEnd": 2877,
|
|
58
|
+
"durationSec": 67.1,
|
|
59
59
|
"testSummary": {
|
|
60
60
|
"totalSpecs": 1728,
|
|
61
61
|
"failures": 0,
|
|
62
62
|
"passed": 1728,
|
|
63
|
-
"testDurationSec":
|
|
63
|
+
"testDurationSec": 9.435
|
|
64
64
|
}
|
|
65
65
|
},
|
|
66
66
|
"npm-publish": {
|
|
67
67
|
"status": "running",
|
|
68
|
-
"startedAt": "2026-08-
|
|
69
|
-
"logLineStart":
|
|
68
|
+
"startedAt": "2026-08-22T10:08:50.633Z",
|
|
69
|
+
"logLineStart": 2878,
|
|
70
70
|
"logLineEnd": null,
|
|
71
71
|
"durationSec": null
|
|
72
72
|
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# NPM-token állapot-osztályozó (FR-320)
|
|
2
|
+
|
|
3
|
+
**Dátum:** 2026-08-22 · **Csomag:** `@futdevpro/nts-dynamo` ≥ `01.15.150` ·
|
|
4
|
+
**Belépési pont:** `checkNpmToken()` + `classifyNpmTokenShape()` / `classifyNpmTokenProbe()`
|
|
5
|
+
|
|
6
|
+
## 1. Miért kellett — a hibaosztály
|
|
7
|
+
|
|
8
|
+
2026-08-20-án a flotta npm-tokenje **lejárt**, majd a pótlására beállított token **nem kapott
|
|
9
|
+
írási / 2FA-bypass jogot**. A diagnózis **több napot és több kört** vitt el, mert az npm
|
|
10
|
+
**létezés-elrejtést** alkalmaz privát csomagnál: a jogosulatlan kérésre **404**-et ad, nem 401-et.
|
|
11
|
+
|
|
12
|
+
**Három külön képesség — mind ugyanazzal a hibakóddal bukik:**
|
|
13
|
+
|
|
14
|
+
| képesség | hibás tokennel | amit az operator lát |
|
|
15
|
+
|---|---|---|
|
|
16
|
+
| olvasás (`GET /@scope%2fpkg`) | **404** | „nincs ilyen csomag" |
|
|
17
|
+
| publikálás (`PUT /@scope%2fpkg`) | **404** | „nincs ilyen csomag" |
|
|
18
|
+
| hitelesítés (`GET /-/whoami`) | **401** | ← az **egyetlen** egyértelmű jel |
|
|
19
|
+
|
|
20
|
+
Emiatt a *„nincs ilyen csomag"*, a *„lejárt kulcs"* és a *„rossz jogú kulcs"* megkülönböztethetetlen
|
|
21
|
+
volt. Élesben ez így nézett ki: `ERR_PNPM_FETCH_404` négy projektben, `npm-publish` némán bukva, és
|
|
22
|
+
egy `PUT … 404`, **miközben ugyanaz a token olvasni tudta a csomagot**.
|
|
23
|
+
|
|
24
|
+
## 2. A kulcs-diszkriminátor
|
|
25
|
+
|
|
26
|
+
**Mindig a `/-/whoami`-val kell kezdeni.** Az **csomag-független**, ezért nem esik a 404-csapdába:
|
|
27
|
+
|
|
28
|
+
- rossz / hiányzó token → **401**
|
|
29
|
+
- érvényes token → **200** + `username`
|
|
30
|
+
|
|
31
|
+
Csak ha ez 200, akkor értelmezhető bármilyen csomag-szintű 404 — és élő token mellett az **mindig
|
|
32
|
+
jogosultság**, sosem hiányzó csomag.
|
|
33
|
+
|
|
34
|
+
## 3. Megkülönböztetett állapotok
|
|
35
|
+
|
|
36
|
+
| állapot | mit jelent | mérés |
|
|
37
|
+
|---|---|---|
|
|
38
|
+
| `missing` | nincs beállítva (env **és** `~/.npmrc`) | helyi, hálózat nélkül |
|
|
39
|
+
| `malformed` | van érték, de nem token-alakú (idézőjel, whitespace, bemásolt `.npmrc`-sor) | helyi |
|
|
40
|
+
| `invalid` | a registry elutasítja | whoami **401** |
|
|
41
|
+
| `no-scope-access` | a token él, de a csomagra nincs joga | whoami 200 + csomag 404/403 |
|
|
42
|
+
| `missing-publish-right` | olvas, de **publikálni nem tud** | whoami 200 + `EOTP`/`E403`/**`E404`** publish-hiba |
|
|
43
|
+
| `ok` | érvényes és a vizsgált csomagot is eléri | whoami 200 + csomag 200 |
|
|
44
|
+
| `unknown` | a próba el sem jutott a registryig | **nem** bizonyíték a token ellen |
|
|
45
|
+
|
|
46
|
+
## 4. Amit szándékosan NEM ígér
|
|
47
|
+
|
|
48
|
+
- A **2FA-bypass hiánya read-only próbával nem állapítható meg** — csak egy már elbukott publish
|
|
49
|
+
hibakódjából (`EOTP`). Ezért van opcionális `publishErrorCode` bemenet.
|
|
50
|
+
- A **lejárt** és a **visszavont** token kívülről egyforma 401.
|
|
51
|
+
- A token **élettartama** nem kérdezhető le.
|
|
52
|
+
- **Granular** tokennél az npm a `readonly`/`automation` mezőket sem teszi közzé
|
|
53
|
+
(`GET /-/npm/v1/tokens` → 200, de a jogok nélkül) — mérve.
|
|
54
|
+
|
|
55
|
+
## 5. Biztonság
|
|
56
|
+
|
|
57
|
+
A **token értéke sosem kerül a kimenetbe** — sem logba, sem eredménybe. A helyi alak-ellenőrzés
|
|
58
|
+
kizárólag minta-illesztés; külön teszt állítja, hogy nincs `cat /root/.npmrc` és nincs
|
|
59
|
+
`echo $NPM_TOKEN`. A `.npmrc`-t **csak olvassuk** — létrehozni flotta-szintű hard rule tiltja.
|
|
60
|
+
|
|
61
|
+
## 6. Használat
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
import { checkNpmToken, DyNTS_NpmTokenState } from '@futdevpro/nts-dynamo';
|
|
65
|
+
|
|
66
|
+
const result = await checkNpmToken({ scopedPackage: '@futdevpro/cli-dynamo' });
|
|
67
|
+
if (result.state !== DyNTS_NpmTokenState.ok) {
|
|
68
|
+
// result.detail = ember-olvasható magyarázat + a KÖVETKEZŐ LÉPÉS
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Token-feloldás prioritása: explicit paraméter → `NPM_TOKEN` env → `~/.npmrc`.
|
|
73
|
+
|
|
74
|
+
## 7. Teszt
|
|
75
|
+
|
|
76
|
+
27 spec. Élesben igazolva mindhárom ág: jó token → `ok` (whoami 200 + csomag 200), érvénytelen →
|
|
77
|
+
`invalid` (401), rossz alak → `malformed`.
|
|
78
|
+
|
|
79
|
+
**Két saját hibát a tesztek/mérés fogtak meg — mindkettő hamis negatív lett volna:**
|
|
80
|
+
|
|
81
|
+
1. Az első változat **csak a `process.env.NPM_TOKEN`-t** nézte → a workstationon `missing`-et adott,
|
|
82
|
+
holott az npm ott működött (a token a `~/.npmrc`-ben áll). Épp a legfontosabb helyeken
|
|
83
|
+
(runner-konténer, hosztok) sült volna el, ahol a token szintén fájlban van.
|
|
84
|
+
2. A host-összehasonlításnál csak az **egyik oldalt** normalizáltam, a `.npmrc` viszont **záró
|
|
85
|
+
perjellel** írja a hostot (`//registry.npmjs.org/`) → sosem illeszkedett.
|
|
86
|
+
|
|
87
|
+
## 8. Kapcsolódó
|
|
88
|
+
|
|
89
|
+
A lánc, ami emiatt állt: `install` (404) → `npm-publish` (💤/❌) → `trigger-runner-cli-hot-update`
|
|
90
|
+
(💤) → **a runnereken befagyott a CLI**. Az automatizmus nem volt hibás, csak **blokkolt** — egyetlen
|
|
91
|
+
ponton. Runner-oldali próba: `fdp-devops` FR-318/FR-319 (`POST /diag/runner/registry-auth` +
|
|
92
|
+
a `fdp diag-all` `2b. RUNNER REGISTRY-AUTH` szekciója).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@futdevpro/nts-dynamo",
|
|
3
|
-
"version": "01.15.
|
|
3
|
+
"version": "01.15.151",
|
|
4
4
|
"description": "Dynamic NodeTS (NodeJS-Typescript), MongoDB Backend System Framework by Future Development Program Ltd.",
|
|
5
5
|
"DyBu_settings": {
|
|
6
6
|
"packageType": "server-package",
|
|
@@ -409,7 +409,7 @@
|
|
|
409
409
|
"@anthropic-ai/sdk": "~0.39.0",
|
|
410
410
|
"@modelcontextprotocol/sdk": "~1.29.0",
|
|
411
411
|
"better-sqlite3": "~12.4.1",
|
|
412
|
-
"@futdevpro/fsm-dynamo": "1.16.
|
|
412
|
+
"@futdevpro/fsm-dynamo": "1.16.40",
|
|
413
413
|
"@types/express": "4.17.21",
|
|
414
414
|
"@types/geoip-lite": "~1.4.1",
|
|
415
415
|
"@types/node": "~24.1.0",
|