@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": 500,
3
- "startedAt": "2026-08-22T06:13:21.680Z",
4
- "startedAtMs": 1787379201680,
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-22T06:13:21.694Z",
13
+ "startedAt": "2026-08-22T10:06:08.682Z",
14
14
  "logLineStart": 2,
15
15
  "logLineEnd": 8,
16
- "durationSec": 2.2
16
+ "durationSec": 2.3
17
17
  },
18
18
  "discord-start": {
19
19
  "status": "ok",
20
- "startedAt": "2026-08-22T06:13:24.944Z",
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-22T06:13:30.925Z",
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-22T06:13:34.138Z",
34
+ "startedAt": "2026-08-22T10:06:21.154Z",
35
35
  "logLineStart": 20,
36
- "logLineEnd": 109,
37
- "durationSec": 32.2
36
+ "logLineEnd": 102,
37
+ "durationSec": 27.9
38
38
  },
39
39
  "check-dev-leftovers": {
40
40
  "status": "ok",
41
- "startedAt": "2026-08-22T06:14:07.438Z",
42
- "logLineStart": 110,
43
- "logLineEnd": 119,
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-22T06:14:14.477Z",
49
- "logLineStart": 120,
50
- "logLineEnd": 121,
51
- "durationSec": 32.4
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-22T06:14:47.932Z",
56
- "logLineStart": 122,
57
- "logLineEnd": 2890,
58
- "durationSec": 30.4,
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": 6.823
63
+ "testDurationSec": 9.435
64
64
  }
65
65
  },
66
66
  "npm-publish": {
67
67
  "status": "running",
68
- "startedAt": "2026-08-22T06:15:19.700Z",
69
- "logLineStart": 2891,
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.150",
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.39",
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",