@runeya/runeya 2.0.48 → 2.0.50
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/agent-manager-ABEKUAWR.js +7 -0
- package/{chunk-JUOZ4L4Y.js → chunk-JBR3MGS7.js} +68 -13
- package/chunk-JBR3MGS7.js.map +1 -0
- package/index.js +1 -1
- package/package.json +1 -1
- package/{src-GMWPTVN2.js → src-LLRT5YLM.js} +36 -7
- package/src-LLRT5YLM.js.map +1 -0
- package/agent-manager-3VUZZC3X.js +0 -7
- package/chunk-JUOZ4L4Y.js.map +0 -1
- package/src-GMWPTVN2.js.map +0 -1
- /package/{agent-manager-3VUZZC3X.js.map → agent-manager-ABEKUAWR.js.map} +0 -0
|
@@ -442,7 +442,7 @@ var agentStore = new AgentStore();
|
|
|
442
442
|
|
|
443
443
|
// ../server/src/services/service-store.ts
|
|
444
444
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
445
|
-
import { readFile as readFile4, writeFile as writeFile4, rename as rename3, mkdir as mkdir4, chmod as chmod3 } from "fs/promises";
|
|
445
|
+
import { readFile as readFile4, writeFile as writeFile4, rename as rename3, mkdir as mkdir4, chmod as chmod3, rm as rm2 } from "fs/promises";
|
|
446
446
|
import { join as join3 } from "path";
|
|
447
447
|
|
|
448
448
|
// ../server/src/services/project-key.ts
|
|
@@ -555,7 +555,7 @@ function isVaultConflicted(root) {
|
|
|
555
555
|
|
|
556
556
|
// ../server/src/services/environment-store.ts
|
|
557
557
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
558
|
-
import { readFile as readFile3, writeFile as writeFile3, rename as rename2, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
|
|
558
|
+
import { readFile as readFile3, writeFile as writeFile3, rename as rename2, mkdir as mkdir3, chmod as chmod2, rm } from "fs/promises";
|
|
559
559
|
import { join as join2 } from "path";
|
|
560
560
|
|
|
561
561
|
// ../server/src/services/crypto-helpers.ts
|
|
@@ -635,7 +635,7 @@ function encryptVariableSlots(variables, existingEncrypted) {
|
|
|
635
635
|
}
|
|
636
636
|
return result;
|
|
637
637
|
}
|
|
638
|
-
function decryptVariableSlots(variables, contextLabel) {
|
|
638
|
+
function decryptVariableSlots(variables, contextLabel, onFailure) {
|
|
639
639
|
const result = {};
|
|
640
640
|
for (const [key, variable] of Object.entries(variables)) {
|
|
641
641
|
const slot = variable.value;
|
|
@@ -643,7 +643,8 @@ function decryptVariableSlots(variables, contextLabel) {
|
|
|
643
643
|
try {
|
|
644
644
|
result[key] = { ...variable, value: { ...slot, value: decryptValue(slot.value) } };
|
|
645
645
|
} catch (err) {
|
|
646
|
-
console.error(`[crypto-helpers] Failed to decrypt variable "${key}" for ${contextLabel}: ${err.message}`);
|
|
646
|
+
console.error(`[crypto-helpers] Failed to decrypt variable "${key}" for ${contextLabel}: ${err.message} \u2014 la valeur chiffr\xE9e est conserv\xE9e telle quelle sur le disque`);
|
|
647
|
+
onFailure?.(key);
|
|
647
648
|
result[key] = { ...variable, value: { ...slot, value: "" } };
|
|
648
649
|
}
|
|
649
650
|
} else {
|
|
@@ -1928,6 +1929,13 @@ var EnvironmentStore = class {
|
|
|
1928
1929
|
loaded = false;
|
|
1929
1930
|
/** Cache of encrypted secret values as last written to disk */
|
|
1930
1931
|
diskEncryptedSlots = /* @__PURE__ */ new Map();
|
|
1932
|
+
/**
|
|
1933
|
+
* Les secrets qu'aucune clé chargée n'a ouverts, par environnement.
|
|
1934
|
+
*
|
|
1935
|
+
* Vides en mémoire, ils doivent repartir sur le disque sous leur forme
|
|
1936
|
+
* chiffrée : c'est ce que retient cette liste. Voir `keepUnreadableSecrets`.
|
|
1937
|
+
*/
|
|
1938
|
+
unreadableSecrets = /* @__PURE__ */ new Map();
|
|
1931
1939
|
listeners = /* @__PURE__ */ new Set();
|
|
1932
1940
|
/** Notified after every persisted mutation, for the cloud sync bridge. */
|
|
1933
1941
|
onChange(fn) {
|
|
@@ -2001,15 +2009,48 @@ var EnvironmentStore = class {
|
|
|
2001
2009
|
cache?.envSlots
|
|
2002
2010
|
);
|
|
2003
2011
|
}
|
|
2004
|
-
return { ...environment, variables: encryptedVars };
|
|
2012
|
+
return { ...environment, variables: this.keepUnreadableSecrets(environment.id, encryptedVars) };
|
|
2013
|
+
}
|
|
2014
|
+
/**
|
|
2015
|
+
* Réécrire un secret illisible tel qu'il est sur le disque, jamais à blanc.
|
|
2016
|
+
*
|
|
2017
|
+
* Un secret qui ne s'ouvre pas est vide en mémoire (voir
|
|
2018
|
+
* `decryptVariableSlots`) : le chiffrer donnerait un chiffré de la chaîne
|
|
2019
|
+
* vide, et la sauvegarde effacerait pour de bon une valeur dont il ne
|
|
2020
|
+
* manquait que la clé. Son chiffré d'origine est encore là — c'est celui que
|
|
2021
|
+
* `diskEncryptedSlots` a mis de côté avant le déchiffrement — et c'est lui
|
|
2022
|
+
* qui repart sur le disque.
|
|
2023
|
+
*
|
|
2024
|
+
* La condition tient à la valeur en mémoire : tant qu'elle est vide, la
|
|
2025
|
+
* variable n'a pas été retouchée et son chiffré fait foi. Dès que
|
|
2026
|
+
* l'utilisateur en saisit une nouvelle, elle l'emporte — et vider un secret
|
|
2027
|
+
* volontairement reste possible, puisque cela ne concerne que les variables
|
|
2028
|
+
* dont le déchiffrement a échoué.
|
|
2029
|
+
*/
|
|
2030
|
+
keepUnreadableSecrets(environmentId, variables) {
|
|
2031
|
+
const failed = this.unreadableSecrets.get(environmentId);
|
|
2032
|
+
if (!failed?.size || !variables) return variables;
|
|
2033
|
+
const onDisk = this.diskEncryptedSlots.get(environmentId)?.envSlots ?? {};
|
|
2034
|
+
const result = { ...variables };
|
|
2035
|
+
for (const variableId of failed) {
|
|
2036
|
+
const ciphertext = onDisk[variableId];
|
|
2037
|
+
const variable = result[variableId];
|
|
2038
|
+
if (!ciphertext || !variable || variable.value.value) continue;
|
|
2039
|
+
result[variableId] = { ...variable, value: { ...variable.value, value: ciphertext } };
|
|
2040
|
+
}
|
|
2041
|
+
return result;
|
|
2005
2042
|
}
|
|
2006
2043
|
decryptEnvironment(environment) {
|
|
2007
2044
|
let decryptedVars = environment.variables;
|
|
2008
2045
|
if (environment.variables && Object.keys(environment.variables).length > 0) {
|
|
2046
|
+
const failed = /* @__PURE__ */ new Set();
|
|
2009
2047
|
decryptedVars = decryptVariableSlots(
|
|
2010
2048
|
environment.variables,
|
|
2011
|
-
`environment ${environment.id}
|
|
2049
|
+
`environment ${environment.id}`,
|
|
2050
|
+
(variableId) => failed.add(variableId)
|
|
2012
2051
|
);
|
|
2052
|
+
if (failed.size > 0) this.unreadableSecrets.set(environment.id, failed);
|
|
2053
|
+
else this.unreadableSecrets.delete(environment.id);
|
|
2013
2054
|
}
|
|
2014
2055
|
return { ...environment, variables: decryptedVars };
|
|
2015
2056
|
}
|
|
@@ -2050,8 +2091,9 @@ var EnvironmentStore = class {
|
|
|
2050
2091
|
/**
|
|
2051
2092
|
* Write each vault that holds — or held — an environment.
|
|
2052
2093
|
*
|
|
2053
|
-
*
|
|
2054
|
-
*
|
|
2094
|
+
* A vault emptied by this save loses its file: an environment that moved to
|
|
2095
|
+
* another vault must not survive in the old one, and a `[]` left behind would
|
|
2096
|
+
* keep (or recreate) a `.runeya` in a directory that holds nothing.
|
|
2055
2097
|
*/
|
|
2056
2098
|
async save() {
|
|
2057
2099
|
const byRoot = /* @__PURE__ */ new Map();
|
|
@@ -2070,8 +2112,13 @@ var EnvironmentStore = class {
|
|
|
2070
2112
|
else byRoot.set(root, [prepared]);
|
|
2071
2113
|
}
|
|
2072
2114
|
for (const [root, environments] of byRoot) {
|
|
2073
|
-
await mkdir3(root, { recursive: true });
|
|
2074
2115
|
const filePath = this.getFilePath(root);
|
|
2116
|
+
if (environments.length === 0) {
|
|
2117
|
+
await rm(filePath, { force: true }).catch(() => {
|
|
2118
|
+
});
|
|
2119
|
+
continue;
|
|
2120
|
+
}
|
|
2121
|
+
await mkdir3(root, { recursive: true });
|
|
2075
2122
|
const tmpPath = filePath + ".tmp";
|
|
2076
2123
|
await writeFile3(tmpPath, JSON.stringify(environments, null, 2), "utf-8");
|
|
2077
2124
|
await rename2(tmpPath, filePath);
|
|
@@ -2111,6 +2158,7 @@ var EnvironmentStore = class {
|
|
|
2111
2158
|
if (environment.projectId !== projectId) continue;
|
|
2112
2159
|
this.environments.delete(id);
|
|
2113
2160
|
this.diskEncryptedSlots.delete(id);
|
|
2161
|
+
this.unreadableSecrets.delete(id);
|
|
2114
2162
|
this.roots.delete(id);
|
|
2115
2163
|
}
|
|
2116
2164
|
this.notify();
|
|
@@ -2347,6 +2395,7 @@ var EnvironmentStore = class {
|
|
|
2347
2395
|
if (!this.environments.has(id)) return false;
|
|
2348
2396
|
this.environments.delete(id);
|
|
2349
2397
|
this.diskEncryptedSlots.delete(id);
|
|
2398
|
+
this.unreadableSecrets.delete(id);
|
|
2350
2399
|
await this.save();
|
|
2351
2400
|
return true;
|
|
2352
2401
|
}
|
|
@@ -2471,8 +2520,9 @@ var ServiceStore = class {
|
|
|
2471
2520
|
/**
|
|
2472
2521
|
* Write each vault that holds — or held — a service.
|
|
2473
2522
|
*
|
|
2474
|
-
* A vault emptied by this save
|
|
2475
|
-
*
|
|
2523
|
+
* A vault emptied by this save loses its file: a service that moved to
|
|
2524
|
+
* another vault must not survive in the one it left, and a `[]` left behind
|
|
2525
|
+
* would keep (or recreate) a `.runeya` in a directory that holds nothing.
|
|
2476
2526
|
*/
|
|
2477
2527
|
async save() {
|
|
2478
2528
|
const byRoot = /* @__PURE__ */ new Map();
|
|
@@ -2491,8 +2541,13 @@ var ServiceStore = class {
|
|
|
2491
2541
|
else byRoot.set(root, [prepared]);
|
|
2492
2542
|
}
|
|
2493
2543
|
for (const [root, services] of byRoot) {
|
|
2494
|
-
await mkdir4(root, { recursive: true });
|
|
2495
2544
|
const filePath = this.getFilePath(root);
|
|
2545
|
+
if (services.length === 0) {
|
|
2546
|
+
await rm2(filePath, { force: true }).catch(() => {
|
|
2547
|
+
});
|
|
2548
|
+
continue;
|
|
2549
|
+
}
|
|
2550
|
+
await mkdir4(root, { recursive: true });
|
|
2496
2551
|
const tmpPath = filePath + ".tmp";
|
|
2497
2552
|
await writeFile4(tmpPath, JSON.stringify(services, null, 2), "utf-8");
|
|
2498
2553
|
await rename3(tmpPath, filePath);
|
|
@@ -3694,4 +3749,4 @@ export {
|
|
|
3694
3749
|
traefikManager,
|
|
3695
3750
|
agentManager
|
|
3696
3751
|
};
|
|
3697
|
-
//# sourceMappingURL=chunk-
|
|
3752
|
+
//# sourceMappingURL=chunk-JBR3MGS7.js.map
|