sliccy 6.129.0 → 6.130.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/README.md +1 -1
- package/dist/node-server/_shared/secret-env-schema.d.ts +22 -0
- package/dist/node-server/_shared/secret-env-schema.d.ts.map +1 -1
- package/dist/node-server/_shared/secret-env-schema.js +28 -0
- package/dist/node-server/_shared/secret-env-schema.js.map +1 -1
- package/dist/node-server/routes/secrets.js +14 -1
- package/dist/node-server/secrets/env-secret-store.js +7 -1
- package/dist/ui/.vite/manifest.json +192 -179
- package/dist/ui/assets/CLAUDE-DhkULx_E.js +1 -0
- package/dist/ui/assets/__vite-browser-external-B19j3y2v.js +1 -0
- package/dist/ui/assets/{account-store-k2cwPcf2.js → account-store-Bt3zihHK.js} +1 -1
- package/dist/ui/assets/{account-store-BdEP74XJ.js → account-store-XKjChfD5.js} +1 -1
- package/dist/ui/assets/{adobe-fbWPKVjt.js → adobe-B7sd2ey1.js} +1 -1
- package/dist/ui/assets/{adobe-BwLPv0hM.js → adobe-DWv_nW7C.js} +1 -1
- package/dist/ui/assets/{agent-bridge-DfHxYJHJ.js → agent-bridge-CmEtyUJl.js} +1 -1
- package/dist/ui/assets/{apply-layout-BJ1rBekE.js → apply-layout-D-QW1Bgf.js} +1 -1
- package/dist/ui/assets/{apps-r9PcIbxT.js → apps-Dl5abdz0.js} +1 -1
- package/dist/ui/assets/{azure-openai-CgYOAd8p.js → azure-openai-CZHEfw9U.js} +1 -1
- package/dist/ui/assets/{azure-openai-DZhCYfxl.js → azure-openai-rq6LQC_C.js} +1 -1
- package/dist/ui/assets/{bsh-watchdog-B13hSKa_.js → bsh-watchdog-D97yX3sQ.js} +1 -1
- package/dist/ui/assets/{capability-Cs03kkRf.js → capability-Btlr4Wc-.js} +2 -2
- package/dist/ui/assets/{cerebras-CiQ7rFfE.js → cerebras-CjhIAx1j.js} +1 -1
- package/dist/ui/assets/{cerebras-h0n808h8.js → cerebras-UuG-yCJ_.js} +1 -1
- package/dist/ui/assets/{composer-speech-CDkeUAGH.js → composer-speech-C8OcijP-.js} +1 -1
- package/dist/ui/assets/{connect-surface-YLhncvhi.js → connect-surface-AitKSc2i.js} +1 -1
- package/dist/ui/assets/{core-xZ6s8sJH.js → core-CdPvxBo3.js} +1 -1
- package/dist/ui/assets/{dip-BLy1TG8X.js → dip-Co-Ga2Ny.js} +1 -1
- package/dist/ui/assets/{directed-approval-8JrfycF7.js → directed-approval-Ca0RuudO.js} +1 -1
- package/dist/ui/assets/{ensure-speech-assets-B1UCV_5w.js → ensure-speech-assets-Csum3_gw.js} +1 -1
- package/dist/ui/assets/{esbuild-wasm-BtINJtvc.js → esbuild-wasm-CSKOA492.js} +1 -1
- package/dist/ui/assets/{extension-media-capture-COQ32TYR.js → extension-media-capture-DiCJSgES.js} +1 -1
- package/dist/ui/assets/{fs-wEN7dsdI.js → fs-0AC_1kYN.js} +2 -2
- package/dist/ui/assets/{fs-BBl_N5G9.js → fs-ClRFZsKp.js} +1 -1
- package/dist/ui/assets/{github-DX02oPjV.js → github-Bo32za86.js} +1 -1
- package/dist/ui/assets/{github-BLiAAyB7.js → github-DA1dJZHt.js} +2 -2
- package/dist/ui/assets/{github-copilot-Bm-BQxfx.js → github-copilot-BlR9rGzE.js} +1 -1
- package/dist/ui/assets/{github-copilot-CbQvhVMh.js → github-copilot-hBCBR7n3.js} +1 -1
- package/dist/ui/assets/{github-install-lVUtA4h4.js → github-install-c-7WlKF0.js} +1 -1
- package/dist/ui/assets/{github-zip-CMgYq_Mz.js → github-zip-BAPGRyWK.js} +1 -1
- package/dist/ui/assets/{guest-tool-gate-AREwJZ9u.js → guest-tool-gate-CG9Yw8Kq.js} +1 -1
- package/dist/ui/assets/{hear-V35zSETD.js → hear-D7MO-jTh.js} +1 -1
- package/dist/ui/assets/{help-a0ozY9CT.js → help-LDG2J6R7.js} +1 -1
- package/dist/ui/assets/{installer-DtOMoVHi.js → installer-7BWtTgd6.js} +1 -1
- package/dist/ui/assets/{js-realm-worker-DA8yxQNR.js → js-realm-worker-CLGBN8Zo.js} +1 -1
- package/dist/ui/assets/{kernel-worker-CaWMG-jx.js → kernel-worker-V_qJr_00.js} +471 -471
- package/dist/ui/assets/{local-llm-2qwDfR7y.js → local-llm-Ko45nuy7.js} +1 -1
- package/dist/ui/assets/{local-llm-BkhpTkPI.js → local-llm-Z6hqEJOJ.js} +1 -1
- package/dist/ui/assets/{magick-wasm-74jUvNbY.js → magick-wasm-BEYfJbAX.js} +1 -1
- package/dist/ui/assets/{main-B6jyx1yC.js → main-DG-TOKaI.js} +3 -3
- package/dist/ui/assets/{mime-types-k2E6ulyv.js → mime-types-D0xZwlMO.js} +1 -1
- package/dist/ui/assets/{mount-DipGtzS7.js → mount-BrmPOs2_.js} +1 -1
- package/dist/ui/assets/{mount-C4oKyNyx.js → mount-O6L8YW8P.js} +3 -3
- package/dist/ui/assets/{mount-recovery-CWdxArDW.js → mount-recovery-lKw_Vyz_.js} +1 -1
- package/dist/ui/assets/{new-session-CqXRbPaf.js → new-session-Bl4ZsQ9b.js} +2 -2
- package/dist/ui/assets/{oauth-bootstrap-vTqMxvjN.js → oauth-bootstrap-Ch6w-P0O.js} +2 -2
- package/dist/ui/assets/{openai-codex-D-AgjjaY.js → openai-codex-39sNBZa4.js} +1 -1
- package/dist/ui/assets/{openai-codex-Ds9ud1Aq.js → openai-codex-DUyhVHOH.js} +1 -1
- package/dist/ui/assets/{openrouter-WdFvkGuZ.js → openrouter-Dpc-slj8.js} +1 -1
- package/dist/ui/assets/{openrouter-zQAB7WS7.js → openrouter-Dt0-tju5.js} +1 -1
- package/dist/ui/assets/{openrouter-oauth-BPGyVeXS.js → openrouter-oauth-Bw9klnns.js} +1 -1
- package/dist/ui/assets/{openrouter-oauth-_dDmj9RY.js → openrouter-oauth-WcOnlgk3.js} +1 -1
- package/dist/ui/assets/panel-rpc-handlers-CRIaZYfR.js +2 -0
- package/dist/ui/assets/{panelize-shell-CazjIR5d.js → panelize-shell-C7Ptpa69.js} +1 -1
- package/dist/ui/assets/preview-url-BvtKejEp.js +1 -0
- package/dist/ui/assets/{provider-RlrlqPhO.js → provider-BKNTonMh.js} +2 -2
- package/dist/ui/assets/{provider-SGu61JcF.js → provider-Bc9U8jIG.js} +1 -1
- package/dist/ui/assets/provider-settings-9D34aQwf.js +1 -0
- package/dist/ui/assets/{provider-settings-CDPm1XM7.js → provider-settings-BdsyHTuR.js} +1 -1
- package/dist/ui/assets/{provider-store-access-CzIObh6x.js → provider-store-access-CvRhpMjO.js} +2 -2
- package/dist/ui/assets/provider-store-access-Dk0cF7LZ.js +1 -0
- package/dist/ui/assets/{providers-CggJCtZV.js → providers-Chea6cTR.js} +1 -1
- package/dist/ui/assets/{providers-V2WCWsve.js → providers-gHHjy3ja.js} +2 -2
- package/dist/ui/assets/{py-realm-worker-BQGDlUNk.js → py-realm-worker-DGFMfg27.js} +2 -2
- package/dist/ui/assets/{pyodide-Cw8OCGih.js → pyodide-BDRAQKP6.js} +2 -2
- package/dist/ui/assets/{quick-llm-9ozW69D2.js → quick-llm-Dg39s0LK.js} +1 -1
- package/dist/ui/assets/{recovery-screen-DtyG3xtc.js → recovery-screen-B5CPvW63.js} +1 -1
- package/dist/ui/assets/rest-ops-31ZkM4IG.js +1 -0
- package/dist/ui/assets/rest-ops-D6OyHX5S.js +1 -0
- package/dist/ui/assets/{run-BC75hCaQ.js → run-BBAgk3Ml.js} +1 -1
- package/dist/ui/assets/{run-DZZ1wNjA.js → run-BMFAdS2O.js} +2 -2
- package/dist/ui/assets/{run-Cayg5JY1.js → run-C31PlCiF.js} +1 -1
- package/dist/ui/assets/{run-7GOuvq0_.js → run-DZMSwK6o.js} +1 -1
- package/dist/ui/assets/{session-freezer-Dts3Ktja.js → session-freezer-DcYjRdMg.js} +3 -3
- package/dist/ui/assets/{setup-feature-flags-remote-NgzCq0Su.js → setup-feature-flags-remote-w6i7-xsn.js} +1 -1
- package/dist/ui/assets/{setup-standalone-prelude-aT6dC0LG.js → setup-standalone-prelude-DFrkjkWu.js} +1 -1
- package/dist/ui/assets/{setup-sudo-CLh8fFfu.js → setup-sudo-C0g6ApHD.js} +2 -2
- package/dist/ui/assets/shared-BpOmrBY4.js +1 -0
- package/dist/ui/assets/{shared-CEdkXLFL.js → shared-CTdWt5ZU.js} +1 -1
- package/dist/ui/assets/{skills-C3pVN-RC.js → skills-DHmzZdlX.js} +1 -1
- package/dist/ui/assets/slicc-version-CVpFSZ60.js +1 -0
- package/dist/ui/assets/{snapshot-u_rfNldX.js → snapshot-CB063Z3h.js} +1 -1
- package/dist/ui/assets/{snapshot-features-CdMjSZ1w.js → snapshot-features-CpPq39XU.js} +1 -1
- package/dist/ui/assets/{speak-CAiWCN3J.js → speak-Dx2FEQBZ.js} +1 -1
- package/dist/ui/assets/sprinkle-bridge-BVfyHi8X.js +2 -0
- package/dist/ui/assets/{sprinkle-manager-BlHamQKs.js → sprinkle-manager-Dxc8U2h1.js} +1 -1
- package/dist/ui/assets/{src-CC79QyGZ.js → src-kInvzkEg.js} +29 -0
- package/dist/ui/assets/{state-B7nfCBnx.js → state-Ct1GOwP8.js} +1 -1
- package/dist/ui/assets/{store-DrtpZOiW.js → store-BiIJ0_As.js} +1 -1
- package/dist/ui/assets/{store-DNT00GaF.js → store-IAZCSKrZ.js} +1 -1
- package/dist/ui/assets/{sudo-DTiL2bcG.js → sudo-llO15-hr.js} +1 -1
- package/dist/ui/assets/transformers-env-DnkszgHP.js +1 -0
- package/dist/ui/assets/{upgrade-detection-XL-DbS1T.js → upgrade-detection-D4-saTZd.js} +1 -1
- package/dist/ui/assets/{voice-reply-CF-palsG.js → voice-reply-BGR2cNZ_.js} +1 -1
- package/dist/ui/assets/{wc-attach-BCVB22e6.js → wc-attach-BLZapYO1.js} +2 -2
- package/dist/ui/assets/{wc-extension-CT5O1Bp9.js → wc-extension-BKv2ap0T.js} +2 -2
- package/dist/ui/assets/{wc-float-label-BpVboxDs.js → wc-float-label-Ck2cAgp3.js} +1 -1
- package/dist/ui/assets/wc-follower-DEUkZTu_.js +17 -0
- package/dist/ui/assets/wc-follower-oauth-CTgC7D7W.js +5 -0
- package/dist/ui/assets/wc-live-DkTXA2Bw.js +8 -0
- package/dist/ui/assets/{wc-nav-CTfWCa-k.js → wc-nav-2fZPqw9y.js} +2 -2
- package/dist/ui/assets/{wc-onboarding-Ddwx2pAn.js → wc-onboarding-C8kBkCKD.js} +2 -2
- package/dist/ui/assets/{wc-placeholder-CB-nwwrA.js → wc-placeholder-CzEI-8XA.js} +2 -2
- package/dist/ui/assets/{wc-settings-C-ZxtQA4.js → wc-settings--cPEMbHv.js} +2 -2
- package/dist/ui/assets/wc-shell-58xXdR-i.js +122 -0
- package/dist/ui/assets/{wc-sprinkles-BDiQQ8lz.js → wc-sprinkles-CN5LWTpu.js} +2 -2
- package/dist/ui/assets/wc-tray-D--vd5uV.js +5 -0
- package/dist/ui/assets/whisper-session-i96-W77q.js +2 -0
- package/dist/ui/assets/{xai-grok-mZX4CDCC.js → xai-grok-0dg6iolO.js} +1 -1
- package/dist/ui/assets/{xai-grok-Bnt5giBD.js → xai-grok-pGpFfbjv.js} +1 -1
- package/dist/ui/index.html +6 -6
- package/dist/ui/llm-proxy-sw.js +1 -1
- package/dist/ui/packages/webapp/index.html +6 -6
- package/dist/ui/preview-sw.js +1 -1
- package/package.json +1 -1
- package/dist/ui/assets/CLAUDE-Bio4HPGK.js +0 -1
- package/dist/ui/assets/__vite-browser-external-CIVB95Zz.js +0 -1
- package/dist/ui/assets/panel-rpc-handlers-BQmhUbHq.js +0 -2
- package/dist/ui/assets/provider-settings-CMSS1i60.js +0 -1
- package/dist/ui/assets/provider-store-access-TwQNg4j0.js +0 -1
- package/dist/ui/assets/rest-ops-BRBsjYZs.js +0 -1
- package/dist/ui/assets/rest-ops-CWNG3-Sx.js +0 -1
- package/dist/ui/assets/shared-BapVZGtv.js +0 -1
- package/dist/ui/assets/slicc-version-DxNGGaVc.js +0 -1
- package/dist/ui/assets/sprinkle-bridge-nsMZiNm5.js +0 -2
- package/dist/ui/assets/transformers-env-4p1QMDFU.js +0 -1
- package/dist/ui/assets/wc-follower-CVbDzcUg.js +0 -17
- package/dist/ui/assets/wc-follower-oauth-CmRMrB5f.js +0 -5
- package/dist/ui/assets/wc-live-CGxuI_qJ.js +0 -8
- package/dist/ui/assets/wc-shell-7EUoAJ_c.js +0 -122
- package/dist/ui/assets/wc-tray-NNzNaeIr.js +0 -5
- package/dist/ui/assets/whisper-session-BTUdcXlN.js +0 -2
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ If this scares, confuses, or excites you, keep reading.
|
|
|
11
11
|
|
|
12
12
|
# slicc — Self-Licking Ice Cream Cone
|
|
13
13
|
|
|
14
|
-
[](https://github.com/ai-ecoverse/vibe-coded-badge-action)
|
|
15
15
|
|
|
16
16
|
[](https://www.npmjs.com/package/sliccy)
|
|
17
17
|
|
|
@@ -12,10 +12,32 @@ export interface SecretEnvEntry {
|
|
|
12
12
|
export declare function parseDomainsCsv(raw: string): string[];
|
|
13
13
|
/** Pair values with non-empty domain companions, preserving first-name order. */
|
|
14
14
|
export declare function pairEnvEntriesToSecrets(entries: EnvEntry[]): SecretEnvEntry[];
|
|
15
|
+
/**
|
|
16
|
+
* Secret values are stored one per line, so a value carrying a line break
|
|
17
|
+
* cannot survive a `serialize` → `parse` round-trip: `serializeEnvFile` quotes
|
|
18
|
+
* it with a real LF inside the quotes and `parseEnvFile` then splits on `\n`,
|
|
19
|
+
* keeping the unbalanced first line and dropping the rest. Writers reject such
|
|
20
|
+
* a value at the boundary instead of silently truncating it (issue #2828).
|
|
21
|
+
*
|
|
22
|
+
* Mirrored by `EnvFileFormat.isSingleLineValue` in
|
|
23
|
+
* `packages/swift-server/Sources/Keychain/EnvFileFormat.swift`; both sides are
|
|
24
|
+
* pinned by the cross-implementation vectors.
|
|
25
|
+
*/
|
|
26
|
+
export declare function isSingleLineSecretValue(value: string): boolean;
|
|
27
|
+
/** The single rejection message both servers return for a multiline value. */
|
|
28
|
+
export declare function multilineSecretValueError(name: string): string;
|
|
15
29
|
/** Parse the shared, deliberately small .env subset used for secret storage. */
|
|
16
30
|
export declare function parseEnvFile(content: string): EnvEntry[];
|
|
17
31
|
/** Parse assignment lines while preserving every character after the first `=`. */
|
|
18
32
|
export declare function parseEnvFilePreservingValues(content: string): EnvEntry[];
|
|
33
|
+
/**
|
|
34
|
+
* Serialize entries to the line-oriented `.env` subset.
|
|
35
|
+
*
|
|
36
|
+
* Throws on a value containing a line break rather than emitting a blob that
|
|
37
|
+
* would parse back truncated. This is the fail-closed backstop behind the
|
|
38
|
+
* boundary checks in the two privileged servers' secret routes — no write path
|
|
39
|
+
* can corrupt the store by going around them.
|
|
40
|
+
*/
|
|
19
41
|
export declare function serializeEnvFile(entries: EnvEntry[]): string;
|
|
20
42
|
/** Profile name validation shared by every S3 secret-schema writer. */
|
|
21
43
|
export declare const PROFILE_RE: RegExp;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secret-env-schema.d.ts","sourceRoot":"","sources":["../src/secret-env-schema.ts"],"names":[],"mappings":"AAAA,qEAAqE;AAErE,eAAO,MAAM,cAAc,aAAa,CAAC;AAEzC,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAKrD;AAED,iFAAiF;AACjF,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,cAAc,EAAE,CAsB7E;AAED,gFAAgF;AAChF,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,EAAE,CAmBxD;AAED,mFAAmF;AACnF,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,EAAE,CAYxE;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"secret-env-schema.d.ts","sourceRoot":"","sources":["../src/secret-env-schema.ts"],"names":[],"mappings":"AAAA,qEAAqE;AAErE,eAAO,MAAM,cAAc,aAAa,CAAC;AAEzC,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAKrD;AAED,iFAAiF;AACjF,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,cAAc,EAAE,CAsB7E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED,8EAA8E;AAC9E,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED,gFAAgF;AAChF,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,EAAE,CAmBxD;AAED,mFAAmF;AACnF,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,EAAE,CAYxE;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,CAQ5D;AAED,uEAAuE;AACvE,eAAO,MAAM,UAAU,QAAsB,CAAC;AAE9C,iFAAiF;AACjF,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,CAStE;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,cAAc,GAAG,mBAAmB,CASjF"}
|
|
@@ -31,6 +31,24 @@ export function pairEnvEntriesToSecrets(entries) {
|
|
|
31
31
|
: [];
|
|
32
32
|
});
|
|
33
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Secret values are stored one per line, so a value carrying a line break
|
|
36
|
+
* cannot survive a `serialize` → `parse` round-trip: `serializeEnvFile` quotes
|
|
37
|
+
* it with a real LF inside the quotes and `parseEnvFile` then splits on `\n`,
|
|
38
|
+
* keeping the unbalanced first line and dropping the rest. Writers reject such
|
|
39
|
+
* a value at the boundary instead of silently truncating it (issue #2828).
|
|
40
|
+
*
|
|
41
|
+
* Mirrored by `EnvFileFormat.isSingleLineValue` in
|
|
42
|
+
* `packages/swift-server/Sources/Keychain/EnvFileFormat.swift`; both sides are
|
|
43
|
+
* pinned by the cross-implementation vectors.
|
|
44
|
+
*/
|
|
45
|
+
export function isSingleLineSecretValue(value) {
|
|
46
|
+
return !/[\n\r]/.test(value);
|
|
47
|
+
}
|
|
48
|
+
/** The single rejection message both servers return for a multiline value. */
|
|
49
|
+
export function multilineSecretValueError(name) {
|
|
50
|
+
return `Secret "${name}" value cannot contain newlines; the secret store is line-oriented and would truncate it to the first line`;
|
|
51
|
+
}
|
|
34
52
|
/** Parse the shared, deliberately small .env subset used for secret storage. */
|
|
35
53
|
export function parseEnvFile(content) {
|
|
36
54
|
const entries = [];
|
|
@@ -68,8 +86,18 @@ export function parseEnvFilePreservingValues(content) {
|
|
|
68
86
|
}
|
|
69
87
|
return entries;
|
|
70
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* Serialize entries to the line-oriented `.env` subset.
|
|
91
|
+
*
|
|
92
|
+
* Throws on a value containing a line break rather than emitting a blob that
|
|
93
|
+
* would parse back truncated. This is the fail-closed backstop behind the
|
|
94
|
+
* boundary checks in the two privileged servers' secret routes — no write path
|
|
95
|
+
* can corrupt the store by going around them.
|
|
96
|
+
*/
|
|
71
97
|
export function serializeEnvFile(entries) {
|
|
72
98
|
const lines = entries.map(({ key, value }) => {
|
|
99
|
+
if (!isSingleLineSecretValue(value))
|
|
100
|
+
throw new Error(multilineSecretValueError(key));
|
|
73
101
|
const needsQuoting = /[\s#"']/.test(value);
|
|
74
102
|
const serialized = needsQuoting ? `"${value.replace(/"/g, '\\"')}"` : value;
|
|
75
103
|
return `${key}=${serialized}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secret-env-schema.js","sourceRoot":"","sources":["../src/secret-env-schema.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"secret-env-schema.js","sourceRoot":"","sources":["../src/secret-env-schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { previewSecret } from '../_shared/index.js';
|
|
1
|
+
import { isSingleLineSecretValue, multilineSecretValueError, previewSecret, } from '../_shared/index.js';
|
|
2
2
|
import express from 'express';
|
|
3
3
|
import { handleDaSignAndForward, handleS3SignAndForward } from '../secrets/sign-and-forward.js';
|
|
4
4
|
/**
|
|
@@ -41,6 +41,12 @@ async function handleScopeEdit(res, name, domains, secretStore, secretProxy) {
|
|
|
41
41
|
const existing = secretStore.get(name);
|
|
42
42
|
if (!existing)
|
|
43
43
|
return res.status(404).json({ error: `no secret named "${name}"` });
|
|
44
|
+
// Re-saving is a full rewrite of the value, so a value the store should
|
|
45
|
+
// never have held (a hand-edited multiline entry) must not be laundered
|
|
46
|
+
// through a scope change into a truncated one (#2828).
|
|
47
|
+
if (!isSingleLineSecretValue(existing.value)) {
|
|
48
|
+
return res.status(400).json({ error: multilineSecretValueError(name) });
|
|
49
|
+
}
|
|
44
50
|
secretStore.set(name, existing.value, domains);
|
|
45
51
|
}
|
|
46
52
|
await secretProxy.reload();
|
|
@@ -122,6 +128,13 @@ export function registerSecretRoutes(app, deps) {
|
|
|
122
128
|
if (typeof name !== 'string' || typeof value !== 'string' || !isStringArray(domains)) {
|
|
123
129
|
return res.status(400).json({ error: 'bad-request' });
|
|
124
130
|
}
|
|
131
|
+
// Fail closed at the boundary: the persisted .env schema stores one value
|
|
132
|
+
// per line, so a multiline value (a PEM private key, typically) would be
|
|
133
|
+
// truncated to its first line — and an overwrite would replace a working
|
|
134
|
+
// credential with an unrecoverable one behind a 200 (#2828).
|
|
135
|
+
if (!isSingleLineSecretValue(value)) {
|
|
136
|
+
return res.status(400).json({ error: multilineSecretValueError(name) });
|
|
137
|
+
}
|
|
125
138
|
try {
|
|
126
139
|
secretStore.set(name, value, domains);
|
|
127
140
|
await secretProxy.reload();
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
10
10
|
import { homedir } from 'node:os';
|
|
11
11
|
import { dirname, resolve } from 'node:path';
|
|
12
|
-
import { DOMAINS_SUFFIX, pairEnvEntriesToSecrets } from '../_shared/index.js';
|
|
12
|
+
import { DOMAINS_SUFFIX, isSingleLineSecretValue, multilineSecretValueError, pairEnvEntriesToSecrets, } from '../_shared/index.js';
|
|
13
13
|
import { parseEnvFile, serializeEnvFile } from './env-file.js';
|
|
14
14
|
const DEFAULT_PATH = resolve(homedir(), '.slicc', 'secrets.env');
|
|
15
15
|
const FILE_MODE = 0o600;
|
|
@@ -25,6 +25,12 @@ export class EnvSecretStore {
|
|
|
25
25
|
if (domains.length === 0) {
|
|
26
26
|
throw new Error(`Secret "${name}" must have at least one authorized domain`);
|
|
27
27
|
}
|
|
28
|
+
// The .env schema is line-oriented, so a multiline value would be written
|
|
29
|
+
// back truncated to its first line (#2828). Refuse the write rather than
|
|
30
|
+
// report success over a corrupted credential.
|
|
31
|
+
if (!isSingleLineSecretValue(value)) {
|
|
32
|
+
throw new Error(multilineSecretValueError(name));
|
|
33
|
+
}
|
|
28
34
|
const entries = this.readEntries();
|
|
29
35
|
const domainsKey = name + DOMAINS_SUFFIX;
|
|
30
36
|
upsertEntry(entries, name, value);
|