@futdevpro/fsm-dynamo 1.16.10 → 1.16.12
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/build/_modules/security/_collections/stored-secret.util.d.ts +40 -0
- package/build/_modules/security/_collections/stored-secret.util.d.ts.map +1 -0
- package/build/_modules/security/_collections/stored-secret.util.js +73 -0
- package/build/_modules/security/_collections/stored-secret.util.js.map +1 -0
- package/build/_modules/security/_models/stored-secret.control-model.d.ts +46 -0
- package/build/_modules/security/_models/stored-secret.control-model.d.ts.map +1 -0
- package/build/_modules/security/_models/stored-secret.control-model.js +54 -0
- package/build/_modules/security/_models/stored-secret.control-model.js.map +1 -0
- package/build/_modules/security/index.d.ts +4 -0
- package/build/_modules/security/index.d.ts.map +1 -0
- package/build/_modules/security/index.js +11 -0
- package/build/_modules/security/index.js.map +1 -0
- package/package.json +8 -2
- package/src/_modules/security/_collections/stored-secret.util.spec.ts +81 -0
- package/src/_modules/security/_collections/stored-secret.util.ts +96 -0
- package/src/_modules/security/_models/stored-secret.control-model.ts +55 -0
- package/src/_modules/security/index.ts +9 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { DyFM_SecretMask_PartialReveal_Interface } from '../../../_collections/utils/secret-mask.util';
|
|
2
|
+
import { DyFM_StoredSecret } from '../_models/stored-secret.control-model';
|
|
3
|
+
/** A levezetett, decrypt-nelkul megjelenitheto resz (a DyFM_StoredSecret masked-mezoi). */
|
|
4
|
+
export interface DyFM_StoredSecret_Preview_Interface {
|
|
5
|
+
maskedPreview: string;
|
|
6
|
+
keyLength: number;
|
|
7
|
+
kind: string | undefined;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* A DyFM_StoredSecret masked-reszenek levezetese egy USER-SAJAT nyers secret-bol — ENCRYPT/DECRYPT
|
|
11
|
+
* NELKUL megjelenitheto azonosito-reszt allit elo (`<prefix>...<suffix>` + a detektalt `kind` +
|
|
12
|
+
* a `keyLength`). A nyers ertek titkositasa NEM itt tortenik (a host/auth adja a kulcsot); ez a
|
|
13
|
+
* util csak a lathato reszt szamolja, hogy a UI / a fogyasztok visszafejtes nelkul azonositsanak.
|
|
14
|
+
*/
|
|
15
|
+
export declare class DyFM_StoredSecret_Util {
|
|
16
|
+
/**
|
|
17
|
+
* A secret fajtajanak detektalasa a kanonikus `DyFM_SECRET_PATTERNS`-szel (egysegesitett a
|
|
18
|
+
* masking-util kind-jeivel, pl. 'openai-key', 'anthropic-key', 'github-pat'). Az elso illeszkedo
|
|
19
|
+
* kind, vagy undefined ha egyik sem ismeri fel.
|
|
20
|
+
*/
|
|
21
|
+
static detectKind(rawSecret: string): string | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* A decrypt-nelkul megjelenitheto preview levezetese. Tul rovid secret-nel (vagy 0/0 reveal-nel)
|
|
24
|
+
* nem reveal-junk semmit (kulonben az egesz secret osszetapadhatna) — ilyenkor tisztan opaque
|
|
25
|
+
* `...` preview. A `keyLength` ettol fuggetlenul mindig a nyers hossz.
|
|
26
|
+
*/
|
|
27
|
+
static derivePreview(rawSecret: string, reveal?: DyFM_SecretMask_PartialReveal_Interface): DyFM_StoredSecret_Preview_Interface;
|
|
28
|
+
/**
|
|
29
|
+
* Egy DyFM_StoredSecret osszeallitasa a USER-SAJAT nyers secret-bol — a masked-reszt levezeti,
|
|
30
|
+
* az `encryptedValue`-t a HIVO adja (a host/auth titkositja a `FDP_PRIVATE_API_KEY_CRYPT_KEY`-jel;
|
|
31
|
+
* a nyers ertek itt csak a preview-levezeteshez kell, NEM tarolodik el nyersen).
|
|
32
|
+
*/
|
|
33
|
+
static build(set: {
|
|
34
|
+
rawSecret: string;
|
|
35
|
+
encryptedValue: string;
|
|
36
|
+
label?: string;
|
|
37
|
+
reveal?: DyFM_SecretMask_PartialReveal_Interface;
|
|
38
|
+
}): DyFM_StoredSecret;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=stored-secret.util.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stored-secret.util.d.ts","sourceRoot":"","sources":["../../../../src/_modules/security/_collections/stored-secret.util.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,uCAAuC,EACxC,MAAM,8CAA8C,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAE3E,2FAA2F;AAC3F,MAAM,WAAW,mCAAmC;IAClD,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1B;AAKD;;;;;GAKG;AACH,qBAAa,sBAAsB;IAEjC;;;;OAIG;IACH,MAAM,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAexD;;;;OAIG;IACH,MAAM,CAAC,aAAa,CAClB,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,uCAAwD,GAC/D,mCAAmC;IAoBtC;;;;OAIG;IACH,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;QACvB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,uCAAuC,CAAC;KAClD,GAAG,iBAAiB;CAatB"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DyFM_StoredSecret_Util = void 0;
|
|
4
|
+
const secret_mask_util_1 = require("../../../_collections/utils/secret-mask.util");
|
|
5
|
+
const stored_secret_control_model_1 = require("../_models/stored-secret.control-model");
|
|
6
|
+
/** Default reveal — az elso 4 + utolso 4 karakter (egysegben a secret-mask util default-javal). */
|
|
7
|
+
const DEFAULT_REVEAL = { prefix: 4, suffix: 4 };
|
|
8
|
+
/**
|
|
9
|
+
* A DyFM_StoredSecret masked-reszenek levezetese egy USER-SAJAT nyers secret-bol — ENCRYPT/DECRYPT
|
|
10
|
+
* NELKUL megjelenitheto azonosito-reszt allit elo (`<prefix>...<suffix>` + a detektalt `kind` +
|
|
11
|
+
* a `keyLength`). A nyers ertek titkositasa NEM itt tortenik (a host/auth adja a kulcsot); ez a
|
|
12
|
+
* util csak a lathato reszt szamolja, hogy a UI / a fogyasztok visszafejtes nelkul azonositsanak.
|
|
13
|
+
*/
|
|
14
|
+
class DyFM_StoredSecret_Util {
|
|
15
|
+
/**
|
|
16
|
+
* A secret fajtajanak detektalasa a kanonikus `DyFM_SECRET_PATTERNS`-szel (egysegesitett a
|
|
17
|
+
* masking-util kind-jeivel, pl. 'openai-key', 'anthropic-key', 'github-pat'). Az elso illeszkedo
|
|
18
|
+
* kind, vagy undefined ha egyik sem ismeri fel.
|
|
19
|
+
*/
|
|
20
|
+
static detectKind(rawSecret) {
|
|
21
|
+
if (!rawSecret) {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
for (const pattern of secret_mask_util_1.DyFM_SECRET_PATTERNS) {
|
|
25
|
+
// a patternek global flag-esek (stateful lastIndex) — minden teszt elott nullazzuk
|
|
26
|
+
pattern.regex.lastIndex = 0;
|
|
27
|
+
if (pattern.regex.test(rawSecret)) {
|
|
28
|
+
pattern.regex.lastIndex = 0;
|
|
29
|
+
return pattern.kind;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A decrypt-nelkul megjelenitheto preview levezetese. Tul rovid secret-nel (vagy 0/0 reveal-nel)
|
|
36
|
+
* nem reveal-junk semmit (kulonben az egesz secret osszetapadhatna) — ilyenkor tisztan opaque
|
|
37
|
+
* `...` preview. A `keyLength` ettol fuggetlenul mindig a nyers hossz.
|
|
38
|
+
*/
|
|
39
|
+
static derivePreview(rawSecret, reveal = DEFAULT_REVEAL) {
|
|
40
|
+
const kind = this.detectKind(rawSecret);
|
|
41
|
+
const keyLength = rawSecret ? rawSecret.length : 0;
|
|
42
|
+
const p = Math.max(0, reveal.prefix);
|
|
43
|
+
const s = Math.max(0, reveal.suffix);
|
|
44
|
+
if (!rawSecret || (p === 0 && s === 0) || rawSecret.length <= p + s + 4) {
|
|
45
|
+
return { maskedPreview: '...', keyLength: keyLength, kind: kind };
|
|
46
|
+
}
|
|
47
|
+
const head = rawSecret.slice(0, p);
|
|
48
|
+
const tail = rawSecret.slice(rawSecret.length - s);
|
|
49
|
+
return {
|
|
50
|
+
maskedPreview: `${head}...${tail}`,
|
|
51
|
+
keyLength: keyLength,
|
|
52
|
+
kind: kind,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Egy DyFM_StoredSecret osszeallitasa a USER-SAJAT nyers secret-bol — a masked-reszt levezeti,
|
|
57
|
+
* az `encryptedValue`-t a HIVO adja (a host/auth titkositja a `FDP_PRIVATE_API_KEY_CRYPT_KEY`-jel;
|
|
58
|
+
* a nyers ertek itt csak a preview-levezeteshez kell, NEM tarolodik el nyersen).
|
|
59
|
+
*/
|
|
60
|
+
static build(set) {
|
|
61
|
+
const preview = this.derivePreview(set.rawSecret, set.reveal ?? DEFAULT_REVEAL);
|
|
62
|
+
return new stored_secret_control_model_1.DyFM_StoredSecret({
|
|
63
|
+
label: set.label,
|
|
64
|
+
kind: preview.kind,
|
|
65
|
+
maskedPreview: preview.maskedPreview,
|
|
66
|
+
keyLength: preview.keyLength,
|
|
67
|
+
encryptedValue: set.encryptedValue,
|
|
68
|
+
isActive: true,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.DyFM_StoredSecret_Util = DyFM_StoredSecret_Util;
|
|
73
|
+
//# sourceMappingURL=stored-secret.util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stored-secret.util.js","sourceRoot":"","sources":["../../../../src/_modules/security/_collections/stored-secret.util.ts"],"names":[],"mappings":";;;AAAA,mFAGsD;AACtD,wFAA2E;AAS3E,mGAAmG;AACnG,MAAM,cAAc,GAA4C,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;AAEzF;;;;;GAKG;AACH,MAAa,sBAAsB;IAEjC;;;;OAIG;IACH,MAAM,CAAC,UAAU,CAAC,SAAiB;QACjC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,KAAK,MAAM,OAAO,IAAI,uCAAoB,EAAE,CAAC;YAC3C,mFAAmF;YACnF,OAAO,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC;YAC5B,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;gBAClC,OAAO,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC;gBAC5B,OAAO,OAAO,CAAC,IAAI,CAAC;YACtB,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,aAAa,CAClB,SAAiB,EACjB,SAAkD,cAAc;QAEhE,MAAM,IAAI,GAAuB,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAC5D,MAAM,SAAS,GAAW,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3D,MAAM,CAAC,GAAW,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAC7C,MAAM,CAAC,GAAW,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAE7C,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,SAAS,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACxE,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACpE,CAAC;QAED,MAAM,IAAI,GAAW,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3C,MAAM,IAAI,GAAW,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAE3D,OAAO;YACL,aAAa,EAAE,GAAG,IAAI,MAAM,IAAI,EAAE;YAClC,SAAS,EAAE,SAAS;YACpB,IAAI,EAAE,IAAI;SACX,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,KAAK,CAAC,GAKZ;QACC,MAAM,OAAO,GACX,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,IAAI,cAAc,CAAC,CAAC;QAElE,OAAO,IAAI,+CAAiB,CAAC;YAC3B,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,cAAc,EAAE,GAAG,CAAC,cAAc;YAClC,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;IACL,CAAC;CACF;AAzED,wDAyEC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Univerzalis tarolt-secret forma (bedrock SSOT) a USER-SAJAT private API-kulcsok / titkos
|
|
3
|
+
* ertekek tarolasara — minden FDP-rendszer ugyanezt hasznalja, igy kozos eredetet kapnak
|
|
4
|
+
* (auth per-user AI-kulcs, Organizer user-kulcs, jovobeli).
|
|
5
|
+
*
|
|
6
|
+
* FONTOS scope: ez a forma a USER altal megadott sajat kulcsokra valo (ezek titkositva
|
|
7
|
+
* tarolodnak a `FDP_PRIVATE_API_KEY_CRYPT_KEY`-jel). Az FDP SAJAT rendszer-api-kulcsai NEM
|
|
8
|
+
* ezen at mennek — azok env-var-ok (nem titkositott DB-tarolas).
|
|
9
|
+
*
|
|
10
|
+
* A lenyeg: a secret-bol tarolaskor levezetheto egy ENCRYPT/DECRYPT NELKUL megjelenitheto
|
|
11
|
+
* azonosito-resz — egy `label` (a user altal beallithato nev) + egy `maskedPreview`
|
|
12
|
+
* (`<prefix>...<suffix>`) + a `kind` (detektalt fajta) + a `keyLength`. Igy a UI / a fogyasztok
|
|
13
|
+
* visszafejtes nelkul azonositjak MELYIK kulcs ez, anelkul hogy a nyers ertek valaha
|
|
14
|
+
* kliensre / logba kerulne.
|
|
15
|
+
*
|
|
16
|
+
* Az `encryptedValue` a titkositott nyers secret — KIZAROLAG szerver-oldalon. A titkositas
|
|
17
|
+
* kulcsa NEM ennek a bedrock-modellnek a felelossege (a host/auth adja a kulcsot a DyFM_Crypto-nak);
|
|
18
|
+
* itt csak a mar titkositott string tarolodik. A masked-mezoket a `DyFM_StoredSecret_Util`
|
|
19
|
+
* szamolja a nyers ertekbol.
|
|
20
|
+
*
|
|
21
|
+
* Embeddable control-model (NEM extends DyFM_Metadata) — provider-config-okba / kulcs-listakba agyazhato.
|
|
22
|
+
*/
|
|
23
|
+
export declare class DyFM_StoredSecret {
|
|
24
|
+
/**
|
|
25
|
+
* A user altal BEALLITHATO megjelenitendo nev (settable feature; a host/UI allitja be, pl.
|
|
26
|
+
* "OpenAI Production"). Decrypt nelkul megjelenitheto; tisztan ember-baratti azonositas.
|
|
27
|
+
*/
|
|
28
|
+
label?: string;
|
|
29
|
+
/** A secret detektalt fajtaja a masking-patternek alapjan (pl. 'openai-key', 'anthropic-key', 'github-pat'). */
|
|
30
|
+
kind?: string;
|
|
31
|
+
/** Decrypt NELKUL megjelenitheto elonezet: `<prefix>...<suffix>` (pl. `sk-a...7890`). */
|
|
32
|
+
maskedPreview?: string;
|
|
33
|
+
/** A nyers secret hossza karakterben — decrypt nelkul megjelenitheto / validalashoz hasznos. */
|
|
34
|
+
keyLength?: number;
|
|
35
|
+
/**
|
|
36
|
+
* A titkositott nyers secret — KIZAROLAG szerver-oldalon. SOHA nem kerul kliensre / logba.
|
|
37
|
+
* A titkositas kulcsa NEM ennek a bedrock-modellnek a felelossege (a host/auth adja); itt csak
|
|
38
|
+
* a mar titkositott string tarolodik.
|
|
39
|
+
*/
|
|
40
|
+
encryptedValue?: string;
|
|
41
|
+
isActive?: boolean;
|
|
42
|
+
expiresAt?: Date;
|
|
43
|
+
lastUsedAt?: Date;
|
|
44
|
+
constructor(set?: DyFM_StoredSecret);
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=stored-secret.control-model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stored-secret.control-model.d.ts","sourceRoot":"","sources":["../../../../src/_modules/security/_models/stored-secret.control-model.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,iBAAiB;IAC5B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,gHAAgH;IAChH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,yFAAyF;IACzF,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,gGAAgG;IAChG,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,UAAU,CAAC,EAAE,IAAI,CAAC;gBAEN,GAAG,CAAC,EAAE,iBAAiB;CAKpC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DyFM_StoredSecret = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Univerzalis tarolt-secret forma (bedrock SSOT) a USER-SAJAT private API-kulcsok / titkos
|
|
6
|
+
* ertekek tarolasara — minden FDP-rendszer ugyanezt hasznalja, igy kozos eredetet kapnak
|
|
7
|
+
* (auth per-user AI-kulcs, Organizer user-kulcs, jovobeli).
|
|
8
|
+
*
|
|
9
|
+
* FONTOS scope: ez a forma a USER altal megadott sajat kulcsokra valo (ezek titkositva
|
|
10
|
+
* tarolodnak a `FDP_PRIVATE_API_KEY_CRYPT_KEY`-jel). Az FDP SAJAT rendszer-api-kulcsai NEM
|
|
11
|
+
* ezen at mennek — azok env-var-ok (nem titkositott DB-tarolas).
|
|
12
|
+
*
|
|
13
|
+
* A lenyeg: a secret-bol tarolaskor levezetheto egy ENCRYPT/DECRYPT NELKUL megjelenitheto
|
|
14
|
+
* azonosito-resz — egy `label` (a user altal beallithato nev) + egy `maskedPreview`
|
|
15
|
+
* (`<prefix>...<suffix>`) + a `kind` (detektalt fajta) + a `keyLength`. Igy a UI / a fogyasztok
|
|
16
|
+
* visszafejtes nelkul azonositjak MELYIK kulcs ez, anelkul hogy a nyers ertek valaha
|
|
17
|
+
* kliensre / logba kerulne.
|
|
18
|
+
*
|
|
19
|
+
* Az `encryptedValue` a titkositott nyers secret — KIZAROLAG szerver-oldalon. A titkositas
|
|
20
|
+
* kulcsa NEM ennek a bedrock-modellnek a felelossege (a host/auth adja a kulcsot a DyFM_Crypto-nak);
|
|
21
|
+
* itt csak a mar titkositott string tarolodik. A masked-mezoket a `DyFM_StoredSecret_Util`
|
|
22
|
+
* szamolja a nyers ertekbol.
|
|
23
|
+
*
|
|
24
|
+
* Embeddable control-model (NEM extends DyFM_Metadata) — provider-config-okba / kulcs-listakba agyazhato.
|
|
25
|
+
*/
|
|
26
|
+
class DyFM_StoredSecret {
|
|
27
|
+
/**
|
|
28
|
+
* A user altal BEALLITHATO megjelenitendo nev (settable feature; a host/UI allitja be, pl.
|
|
29
|
+
* "OpenAI Production"). Decrypt nelkul megjelenitheto; tisztan ember-baratti azonositas.
|
|
30
|
+
*/
|
|
31
|
+
label;
|
|
32
|
+
/** A secret detektalt fajtaja a masking-patternek alapjan (pl. 'openai-key', 'anthropic-key', 'github-pat'). */
|
|
33
|
+
kind;
|
|
34
|
+
/** Decrypt NELKUL megjelenitheto elonezet: `<prefix>...<suffix>` (pl. `sk-a...7890`). */
|
|
35
|
+
maskedPreview;
|
|
36
|
+
/** A nyers secret hossza karakterben — decrypt nelkul megjelenitheto / validalashoz hasznos. */
|
|
37
|
+
keyLength;
|
|
38
|
+
/**
|
|
39
|
+
* A titkositott nyers secret — KIZAROLAG szerver-oldalon. SOHA nem kerul kliensre / logba.
|
|
40
|
+
* A titkositas kulcsa NEM ennek a bedrock-modellnek a felelossege (a host/auth adja); itt csak
|
|
41
|
+
* a mar titkositott string tarolodik.
|
|
42
|
+
*/
|
|
43
|
+
encryptedValue;
|
|
44
|
+
isActive;
|
|
45
|
+
expiresAt;
|
|
46
|
+
lastUsedAt;
|
|
47
|
+
constructor(set) {
|
|
48
|
+
if (set) {
|
|
49
|
+
Object.assign(this, set);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
exports.DyFM_StoredSecret = DyFM_StoredSecret;
|
|
54
|
+
//# sourceMappingURL=stored-secret.control-model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stored-secret.control-model.js","sourceRoot":"","sources":["../../../../src/_modules/security/_models/stored-secret.control-model.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAa,iBAAiB;IAC5B;;;OAGG;IACH,KAAK,CAAU;IAEf,gHAAgH;IAChH,IAAI,CAAU;IAEd,yFAAyF;IACzF,aAAa,CAAU;IAEvB,gGAAgG;IAChG,SAAS,CAAU;IAEnB;;;;OAIG;IACH,cAAc,CAAU;IAExB,QAAQ,CAAW;IACnB,SAAS,CAAQ;IACjB,UAAU,CAAQ;IAElB,YAAY,GAAuB;QACjC,IAAI,GAAG,EAAE,CAAC;YACR,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;CACF;AAhCD,8CAgCC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/_modules/security/index.ts"],"names":[],"mappings":"AAIA,cAAc,uCAAuC,CAAC;AACtD,cAAc,mCAAmC,CAAC;AAGlD,cAAc,2CAA2C,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// security ("out + security alapok") modul — a titkos-ertek tarolas/maszkolas bedrock SSOT-ja.
|
|
3
|
+
// Erre epit minden FDP-rendszer (auth per-user AI-kulcs, Organizer MCP-kulcs, rendszer-kulcsok):
|
|
4
|
+
// kozos forma (DyFM_StoredSecret) + decrypt-nelkuli preview-derive + a meglevo secret-maszkolas.
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const tslib_1 = require("tslib");
|
|
7
|
+
tslib_1.__exportStar(require("./_models/stored-secret.control-model"), exports);
|
|
8
|
+
tslib_1.__exportStar(require("./_collections/stored-secret.util"), exports);
|
|
9
|
+
// a mar letezo univerzalis secret-maszkolas (log/output-redaction) is innen elerheto, egy helyrol
|
|
10
|
+
tslib_1.__exportStar(require("../../_collections/utils/secret-mask.util"), exports);
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/_modules/security/index.ts"],"names":[],"mappings":";AAAA,+FAA+F;AAC/F,iGAAiG;AACjG,iGAAiG;;;AAEjG,gFAAsD;AACtD,4EAAkD;AAElD,kGAAkG;AAClG,oFAA0D"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@futdevpro/fsm-dynamo",
|
|
3
|
-
"version": "01.16.
|
|
3
|
+
"version": "01.16.12",
|
|
4
4
|
"description": "Full Stack Model Collection for Dynamic (NodeJS-Typescript) Framework called Dynamo, by Future Development Ltd.",
|
|
5
5
|
"DyBu_settings": {
|
|
6
6
|
"packageType": "full-stack-package",
|
|
@@ -152,6 +152,12 @@
|
|
|
152
152
|
"types": "./build/_modules/pipe/index.d.ts",
|
|
153
153
|
"typings": "./build/_modules/pipe/index.d.ts"
|
|
154
154
|
},
|
|
155
|
+
"./security": {
|
|
156
|
+
"default": "./build/_modules/security/index.js",
|
|
157
|
+
"module": "./build/_modules/security/index.js",
|
|
158
|
+
"types": "./build/_modules/security/index.d.ts",
|
|
159
|
+
"typings": "./build/_modules/security/index.d.ts"
|
|
160
|
+
},
|
|
155
161
|
"./socket": {
|
|
156
162
|
"default": "./build/_modules/socket/index.js",
|
|
157
163
|
"module": "./build/_modules/socket/index.js",
|
|
@@ -269,7 +275,7 @@
|
|
|
269
275
|
"uuid": "11.1.0"
|
|
270
276
|
},
|
|
271
277
|
"devDependencies": {
|
|
272
|
-
"@futdevpro/dynamo-eslint": "1.15.
|
|
278
|
+
"@futdevpro/dynamo-eslint": "1.15.18",
|
|
273
279
|
"@types/jasmine": "~4.3.5",
|
|
274
280
|
"@typescript-eslint/eslint-plugin": "^8.41.0",
|
|
275
281
|
"@typescript-eslint/parser": "^8.41.0",
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { DyFM_StoredSecret } from '../_models/stored-secret.control-model';
|
|
2
|
+
import { DyFM_StoredSecret_Util } from './stored-secret.util';
|
|
3
|
+
|
|
4
|
+
describe('| DyFM_StoredSecret_Util', () => {
|
|
5
|
+
|
|
6
|
+
// valid-formatumu teszt-kulcsok (a DyFM_SECRET_PATTERNS-hez igazitva)
|
|
7
|
+
const openAiKey: string = 'sk-abcdefghij1234567890abcdefghij1234567890';
|
|
8
|
+
const anthropicKey: string = 'sk-ant-abcdefghij1234567890abcdefghij1234567890';
|
|
9
|
+
const githubPat: string = 'ghp_abcdefghij1234567890abcdefghij1234567890';
|
|
10
|
+
|
|
11
|
+
describe('| detectKind', () => {
|
|
12
|
+
it('| OpenAI kulcsot felismer', () => {
|
|
13
|
+
expect(DyFM_StoredSecret_Util.detectKind(openAiKey)).toBe('openai-key');
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('| Anthropic kulcsot felismer (a sk-ant- specifikusabb mint a sk-)', () => {
|
|
17
|
+
expect(DyFM_StoredSecret_Util.detectKind(anthropicKey)).toBe('anthropic-key');
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('| GitHub PAT-ot felismer', () => {
|
|
21
|
+
expect(DyFM_StoredSecret_Util.detectKind(githubPat)).toBe('github-pat');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('| ismeretlen formatumra undefined', () => {
|
|
25
|
+
expect(DyFM_StoredSecret_Util.detectKind('not-a-known-secret-format')).toBeUndefined();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('| ures inputra undefined', () => {
|
|
29
|
+
expect(DyFM_StoredSecret_Util.detectKind('')).toBeUndefined();
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
describe('| derivePreview', () => {
|
|
34
|
+
it('| normal kulcsbol maskedPreview + keyLength + kind', () => {
|
|
35
|
+
const preview = DyFM_StoredSecret_Util.derivePreview(openAiKey);
|
|
36
|
+
expect(preview.maskedPreview).toBe('sk-a...7890');
|
|
37
|
+
expect(preview.keyLength).toBe(openAiKey.length);
|
|
38
|
+
expect(preview.kind).toBe('openai-key');
|
|
39
|
+
// a nyers kulcs SOHA nem jelenik meg teljes egeszeben a preview-ban
|
|
40
|
+
expect(preview.maskedPreview).not.toContain('abcdefghij');
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('| tul rovid secret -> opaque preview, de keyLength megvan', () => {
|
|
44
|
+
const preview = DyFM_StoredSecret_Util.derivePreview('short');
|
|
45
|
+
expect(preview.maskedPreview).toBe('...');
|
|
46
|
+
expect(preview.keyLength).toBe(5);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('| 0/0 reveal -> opaque', () => {
|
|
50
|
+
const preview = DyFM_StoredSecret_Util.derivePreview(openAiKey, { prefix: 0, suffix: 0 });
|
|
51
|
+
expect(preview.maskedPreview).toBe('...');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('| ures input -> opaque + keyLength 0', () => {
|
|
55
|
+
const preview = DyFM_StoredSecret_Util.derivePreview('');
|
|
56
|
+
expect(preview.maskedPreview).toBe('...');
|
|
57
|
+
expect(preview.keyLength).toBe(0);
|
|
58
|
+
expect(preview.kind).toBeUndefined();
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
describe('| build', () => {
|
|
63
|
+
it('| osszeallit egy DyFM_StoredSecret-et a masked-reszekkel + encryptedValue-val', () => {
|
|
64
|
+
const secret: DyFM_StoredSecret = DyFM_StoredSecret_Util.build({
|
|
65
|
+
rawSecret: anthropicKey,
|
|
66
|
+
encryptedValue: 'ENCRYPTED-BLOB-xyz',
|
|
67
|
+
label: 'Anthropic Prod',
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
expect(secret.label).toBe('Anthropic Prod');
|
|
71
|
+
expect(secret.kind).toBe('anthropic-key');
|
|
72
|
+
expect(secret.maskedPreview).toBe('sk-a...7890');
|
|
73
|
+
expect(secret.keyLength).toBe(anthropicKey.length);
|
|
74
|
+
expect(secret.encryptedValue).toBe('ENCRYPTED-BLOB-xyz');
|
|
75
|
+
expect(secret.isActive).toBe(true);
|
|
76
|
+
// a nyers kulcs NINCS eltarolva a modellben (csak az encryptedValue + a masked-resz)
|
|
77
|
+
expect(JSON.stringify(secret)).not.toContain('abcdefghij');
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
});
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DyFM_SECRET_PATTERNS,
|
|
3
|
+
DyFM_SecretMask_PartialReveal_Interface,
|
|
4
|
+
} from '../../../_collections/utils/secret-mask.util';
|
|
5
|
+
import { DyFM_StoredSecret } from '../_models/stored-secret.control-model';
|
|
6
|
+
|
|
7
|
+
/** A levezetett, decrypt-nelkul megjelenitheto resz (a DyFM_StoredSecret masked-mezoi). */
|
|
8
|
+
export interface DyFM_StoredSecret_Preview_Interface {
|
|
9
|
+
maskedPreview: string;
|
|
10
|
+
keyLength: number;
|
|
11
|
+
kind: string | undefined;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** Default reveal — az elso 4 + utolso 4 karakter (egysegben a secret-mask util default-javal). */
|
|
15
|
+
const DEFAULT_REVEAL: DyFM_SecretMask_PartialReveal_Interface = { prefix: 4, suffix: 4 };
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* A DyFM_StoredSecret masked-reszenek levezetese egy USER-SAJAT nyers secret-bol — ENCRYPT/DECRYPT
|
|
19
|
+
* NELKUL megjelenitheto azonosito-reszt allit elo (`<prefix>...<suffix>` + a detektalt `kind` +
|
|
20
|
+
* a `keyLength`). A nyers ertek titkositasa NEM itt tortenik (a host/auth adja a kulcsot); ez a
|
|
21
|
+
* util csak a lathato reszt szamolja, hogy a UI / a fogyasztok visszafejtes nelkul azonositsanak.
|
|
22
|
+
*/
|
|
23
|
+
export class DyFM_StoredSecret_Util {
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* A secret fajtajanak detektalasa a kanonikus `DyFM_SECRET_PATTERNS`-szel (egysegesitett a
|
|
27
|
+
* masking-util kind-jeivel, pl. 'openai-key', 'anthropic-key', 'github-pat'). Az elso illeszkedo
|
|
28
|
+
* kind, vagy undefined ha egyik sem ismeri fel.
|
|
29
|
+
*/
|
|
30
|
+
static detectKind(rawSecret: string): string | undefined {
|
|
31
|
+
if (!rawSecret) {
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
for (const pattern of DyFM_SECRET_PATTERNS) {
|
|
35
|
+
// a patternek global flag-esek (stateful lastIndex) — minden teszt elott nullazzuk
|
|
36
|
+
pattern.regex.lastIndex = 0;
|
|
37
|
+
if (pattern.regex.test(rawSecret)) {
|
|
38
|
+
pattern.regex.lastIndex = 0;
|
|
39
|
+
return pattern.kind;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* A decrypt-nelkul megjelenitheto preview levezetese. Tul rovid secret-nel (vagy 0/0 reveal-nel)
|
|
47
|
+
* nem reveal-junk semmit (kulonben az egesz secret osszetapadhatna) — ilyenkor tisztan opaque
|
|
48
|
+
* `...` preview. A `keyLength` ettol fuggetlenul mindig a nyers hossz.
|
|
49
|
+
*/
|
|
50
|
+
static derivePreview(
|
|
51
|
+
rawSecret: string,
|
|
52
|
+
reveal: DyFM_SecretMask_PartialReveal_Interface = DEFAULT_REVEAL,
|
|
53
|
+
): DyFM_StoredSecret_Preview_Interface {
|
|
54
|
+
const kind: string | undefined = this.detectKind(rawSecret);
|
|
55
|
+
const keyLength: number = rawSecret ? rawSecret.length : 0;
|
|
56
|
+
const p: number = Math.max(0, reveal.prefix);
|
|
57
|
+
const s: number = Math.max(0, reveal.suffix);
|
|
58
|
+
|
|
59
|
+
if (!rawSecret || (p === 0 && s === 0) || rawSecret.length <= p + s + 4) {
|
|
60
|
+
return { maskedPreview: '...', keyLength: keyLength, kind: kind };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const head: string = rawSecret.slice(0, p);
|
|
64
|
+
const tail: string = rawSecret.slice(rawSecret.length - s);
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
maskedPreview: `${head}...${tail}`,
|
|
68
|
+
keyLength: keyLength,
|
|
69
|
+
kind: kind,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Egy DyFM_StoredSecret osszeallitasa a USER-SAJAT nyers secret-bol — a masked-reszt levezeti,
|
|
75
|
+
* az `encryptedValue`-t a HIVO adja (a host/auth titkositja a `FDP_PRIVATE_API_KEY_CRYPT_KEY`-jel;
|
|
76
|
+
* a nyers ertek itt csak a preview-levezeteshez kell, NEM tarolodik el nyersen).
|
|
77
|
+
*/
|
|
78
|
+
static build(set: {
|
|
79
|
+
rawSecret: string,
|
|
80
|
+
encryptedValue: string,
|
|
81
|
+
label?: string,
|
|
82
|
+
reveal?: DyFM_SecretMask_PartialReveal_Interface,
|
|
83
|
+
}): DyFM_StoredSecret {
|
|
84
|
+
const preview: DyFM_StoredSecret_Preview_Interface =
|
|
85
|
+
this.derivePreview(set.rawSecret, set.reveal ?? DEFAULT_REVEAL);
|
|
86
|
+
|
|
87
|
+
return new DyFM_StoredSecret({
|
|
88
|
+
label: set.label,
|
|
89
|
+
kind: preview.kind,
|
|
90
|
+
maskedPreview: preview.maskedPreview,
|
|
91
|
+
keyLength: preview.keyLength,
|
|
92
|
+
encryptedValue: set.encryptedValue,
|
|
93
|
+
isActive: true,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Univerzalis tarolt-secret forma (bedrock SSOT) a USER-SAJAT private API-kulcsok / titkos
|
|
3
|
+
* ertekek tarolasara — minden FDP-rendszer ugyanezt hasznalja, igy kozos eredetet kapnak
|
|
4
|
+
* (auth per-user AI-kulcs, Organizer user-kulcs, jovobeli).
|
|
5
|
+
*
|
|
6
|
+
* FONTOS scope: ez a forma a USER altal megadott sajat kulcsokra valo (ezek titkositva
|
|
7
|
+
* tarolodnak a `FDP_PRIVATE_API_KEY_CRYPT_KEY`-jel). Az FDP SAJAT rendszer-api-kulcsai NEM
|
|
8
|
+
* ezen at mennek — azok env-var-ok (nem titkositott DB-tarolas).
|
|
9
|
+
*
|
|
10
|
+
* A lenyeg: a secret-bol tarolaskor levezetheto egy ENCRYPT/DECRYPT NELKUL megjelenitheto
|
|
11
|
+
* azonosito-resz — egy `label` (a user altal beallithato nev) + egy `maskedPreview`
|
|
12
|
+
* (`<prefix>...<suffix>`) + a `kind` (detektalt fajta) + a `keyLength`. Igy a UI / a fogyasztok
|
|
13
|
+
* visszafejtes nelkul azonositjak MELYIK kulcs ez, anelkul hogy a nyers ertek valaha
|
|
14
|
+
* kliensre / logba kerulne.
|
|
15
|
+
*
|
|
16
|
+
* Az `encryptedValue` a titkositott nyers secret — KIZAROLAG szerver-oldalon. A titkositas
|
|
17
|
+
* kulcsa NEM ennek a bedrock-modellnek a felelossege (a host/auth adja a kulcsot a DyFM_Crypto-nak);
|
|
18
|
+
* itt csak a mar titkositott string tarolodik. A masked-mezoket a `DyFM_StoredSecret_Util`
|
|
19
|
+
* szamolja a nyers ertekbol.
|
|
20
|
+
*
|
|
21
|
+
* Embeddable control-model (NEM extends DyFM_Metadata) — provider-config-okba / kulcs-listakba agyazhato.
|
|
22
|
+
*/
|
|
23
|
+
export class DyFM_StoredSecret {
|
|
24
|
+
/**
|
|
25
|
+
* A user altal BEALLITHATO megjelenitendo nev (settable feature; a host/UI allitja be, pl.
|
|
26
|
+
* "OpenAI Production"). Decrypt nelkul megjelenitheto; tisztan ember-baratti azonositas.
|
|
27
|
+
*/
|
|
28
|
+
label?: string;
|
|
29
|
+
|
|
30
|
+
/** A secret detektalt fajtaja a masking-patternek alapjan (pl. 'openai-key', 'anthropic-key', 'github-pat'). */
|
|
31
|
+
kind?: string;
|
|
32
|
+
|
|
33
|
+
/** Decrypt NELKUL megjelenitheto elonezet: `<prefix>...<suffix>` (pl. `sk-a...7890`). */
|
|
34
|
+
maskedPreview?: string;
|
|
35
|
+
|
|
36
|
+
/** A nyers secret hossza karakterben — decrypt nelkul megjelenitheto / validalashoz hasznos. */
|
|
37
|
+
keyLength?: number;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* A titkositott nyers secret — KIZAROLAG szerver-oldalon. SOHA nem kerul kliensre / logba.
|
|
41
|
+
* A titkositas kulcsa NEM ennek a bedrock-modellnek a felelossege (a host/auth adja); itt csak
|
|
42
|
+
* a mar titkositott string tarolodik.
|
|
43
|
+
*/
|
|
44
|
+
encryptedValue?: string;
|
|
45
|
+
|
|
46
|
+
isActive?: boolean;
|
|
47
|
+
expiresAt?: Date;
|
|
48
|
+
lastUsedAt?: Date;
|
|
49
|
+
|
|
50
|
+
constructor(set?: DyFM_StoredSecret) {
|
|
51
|
+
if (set) {
|
|
52
|
+
Object.assign(this, set);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// security ("out + security alapok") modul — a titkos-ertek tarolas/maszkolas bedrock SSOT-ja.
|
|
2
|
+
// Erre epit minden FDP-rendszer (auth per-user AI-kulcs, Organizer MCP-kulcs, rendszer-kulcsok):
|
|
3
|
+
// kozos forma (DyFM_StoredSecret) + decrypt-nelkuli preview-derive + a meglevo secret-maszkolas.
|
|
4
|
+
|
|
5
|
+
export * from './_models/stored-secret.control-model';
|
|
6
|
+
export * from './_collections/stored-secret.util';
|
|
7
|
+
|
|
8
|
+
// a mar letezo univerzalis secret-maszkolas (log/output-redaction) is innen elerheto, egy helyrol
|
|
9
|
+
export * from '../../_collections/utils/secret-mask.util';
|