@getmyenv/crypto 0.1.0 → 0.2.0
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/LICENSE +1 -1
- package/README.md +2 -0
- package/dist/backup.d.ts +17 -18
- package/dist/backup.d.ts.map +1 -1
- package/dist/backup.js +22 -16
- package/dist/backup.js.map +1 -1
- package/dist/identity.d.ts +4 -4
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +1 -1
- package/dist/identity.js.map +1 -1
- package/dist/types.d.ts +20 -9
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -1
- package/package.json +3 -1
- package/dist/envelope.test.d.ts +0 -2
- package/dist/envelope.test.d.ts.map +0 -1
- package/dist/envelope.test.js +0 -66
- package/dist/envelope.test.js.map +0 -1
package/LICENSE
CHANGED
package/README.md
CHANGED
package/dist/backup.d.ts
CHANGED
|
@@ -1,29 +1,28 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { BackupContext, BackupValue, EncryptedBackupEnvelope, WrappedProjectKey } from "./types.js";
|
|
2
2
|
import { encryptSecret, decryptSecret } from "./envelope.js";
|
|
3
3
|
export declare function createBackupEnvelope(input: {
|
|
4
4
|
projectName: string;
|
|
5
5
|
wrappedProjectKey: WrappedProjectKey;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
expiresAt: string | null;
|
|
11
|
-
payload: EncryptedSecretPayload | null;
|
|
12
|
-
}>;
|
|
6
|
+
contexts: BackupContext[];
|
|
7
|
+
keys: string[];
|
|
8
|
+
tags?: Record<string, string>;
|
|
9
|
+
values: BackupValue[];
|
|
13
10
|
}): EncryptedBackupEnvelope;
|
|
14
11
|
export declare function serializeBackup(envelope: EncryptedBackupEnvelope): string;
|
|
15
12
|
export declare function parseBackup(raw: string): EncryptedBackupEnvelope;
|
|
16
13
|
/**
|
|
17
|
-
* Decrypt
|
|
18
|
-
*
|
|
19
|
-
* Placeholders (null payload) restore as empty values.
|
|
14
|
+
* Decrypt every value in a backup with the Vault password.
|
|
15
|
+
* Works without getmyenv being reachable.
|
|
20
16
|
*/
|
|
21
|
-
export declare function
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
17
|
+
export declare function restoreValuesFromBackup(vaultPassword: string, envelope: EncryptedBackupEnvelope): Promise<{
|
|
18
|
+
contexts: BackupContext[];
|
|
19
|
+
keys: string[];
|
|
20
|
+
values: Array<{
|
|
21
|
+
key: string;
|
|
22
|
+
context: string;
|
|
23
|
+
value: string;
|
|
24
|
+
expiresAt: string | null;
|
|
25
|
+
}>;
|
|
26
|
+
}>;
|
|
28
27
|
export { encryptSecret, decryptSecret };
|
|
29
28
|
//# sourceMappingURL=backup.d.ts.map
|
package/dist/backup.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backup.d.ts","sourceRoot":"","sources":["../src/backup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"backup.d.ts","sourceRoot":"","sources":["../src/backup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,WAAW,EACX,uBAAuB,EACvB,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,aAAa,EAAE,aAAa,EAAoB,MAAM,eAAe,CAAC;AAE/E,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAC1C,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB,GAAG,uBAAuB,CAa1B;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,uBAAuB,GAAG,MAAM,CAEzE;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,uBAAuB,CAShE;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,uBAAuB,GAChC,OAAO,CAAC;IACT,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,MAAM,EAAE,KAAK,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC;QACZ,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;KAC1B,CAAC,CAAC;CACJ,CAAC,CAYD;AAED,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,CAAC"}
|
package/dist/backup.js
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BACKUP_FORMAT_VERSION } from "./types.js";
|
|
2
2
|
import { encryptSecret, decryptSecret, unwrapProjectKey } from "./envelope.js";
|
|
3
3
|
export function createBackupEnvelope(input) {
|
|
4
|
+
const hasTags = input.tags && Object.keys(input.tags).length > 0;
|
|
4
5
|
return {
|
|
5
6
|
format: "getmyenv-backup",
|
|
6
|
-
version:
|
|
7
|
+
version: BACKUP_FORMAT_VERSION,
|
|
7
8
|
createdAt: new Date().toISOString(),
|
|
8
9
|
projectName: input.projectName,
|
|
9
10
|
wrappedProjectKey: input.wrappedProjectKey,
|
|
10
|
-
|
|
11
|
+
contexts: input.contexts,
|
|
12
|
+
keys: input.keys,
|
|
13
|
+
...(hasTags ? { tags: input.tags } : {}),
|
|
14
|
+
values: input.values,
|
|
11
15
|
};
|
|
12
16
|
}
|
|
13
17
|
export function serializeBackup(envelope) {
|
|
@@ -18,25 +22,27 @@ export function parseBackup(raw) {
|
|
|
18
22
|
if (parsed.format !== "getmyenv-backup") {
|
|
19
23
|
throw new Error("Not a getmyenv backup file");
|
|
20
24
|
}
|
|
21
|
-
if (parsed.version !==
|
|
22
|
-
throw new Error(`Unsupported backup version: ${parsed.version}`);
|
|
25
|
+
if (parsed.version !== BACKUP_FORMAT_VERSION) {
|
|
26
|
+
throw new Error(`Unsupported backup version: ${String(parsed.version)}`);
|
|
23
27
|
}
|
|
24
28
|
return parsed;
|
|
25
29
|
}
|
|
26
30
|
/**
|
|
27
|
-
* Decrypt
|
|
28
|
-
*
|
|
29
|
-
* Placeholders (null payload) restore as empty values.
|
|
31
|
+
* Decrypt every value in a backup with the Vault password.
|
|
32
|
+
* Works without getmyenv being reachable.
|
|
30
33
|
*/
|
|
31
|
-
export async function
|
|
34
|
+
export async function restoreValuesFromBackup(vaultPassword, envelope) {
|
|
32
35
|
const pek = await unwrapProjectKey(vaultPassword, envelope.wrappedProjectKey);
|
|
33
|
-
return
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
return {
|
|
37
|
+
contexts: envelope.contexts,
|
|
38
|
+
keys: envelope.keys,
|
|
39
|
+
values: envelope.values.map((v) => ({
|
|
40
|
+
key: v.key,
|
|
41
|
+
context: v.context,
|
|
42
|
+
value: decryptSecret(pek, v.payload),
|
|
43
|
+
expiresAt: v.expiresAt,
|
|
44
|
+
})),
|
|
45
|
+
};
|
|
40
46
|
}
|
|
41
47
|
export { encryptSecret, decryptSecret };
|
|
42
48
|
//# sourceMappingURL=backup.js.map
|
package/dist/backup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backup.js","sourceRoot":"","sources":["../src/backup.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"backup.js","sourceRoot":"","sources":["../src/backup.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAE/E,MAAM,UAAU,oBAAoB,CAAC,KAOpC;IACC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IACjE,OAAO;QACL,MAAM,EAAE,iBAAiB;QACzB,OAAO,EAAE,qBAAqB;QAC9B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;QAC1C,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxC,MAAM,EAAE,KAAK,CAAC,MAAM;KACrB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,QAAiC;IAC/D,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA4C,CAAC;IAC1E,IAAI,MAAM,CAAC,MAAM,KAAK,iBAAiB,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAChD,CAAC;IACD,IAAI,MAAM,CAAC,OAAO,KAAK,qBAAqB,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,+BAA+B,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,MAAiC,CAAC;AAC3C,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,aAAqB,EACrB,QAAiC;IAWjC,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,aAAa,EAAE,QAAQ,CAAC,iBAAiB,CAAC,CAAC;IAC9E,OAAO;QACL,QAAQ,EAAE,QAAQ,CAAC,QAAQ;QAC3B,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAClC,GAAG,EAAE,CAAC,CAAC,GAAG;YACV,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,KAAK,EAAE,aAAa,CAAC,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC;YACpC,SAAS,EAAE,CAAC,CAAC,SAAS;SACvB,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC;AAED,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,CAAC"}
|
package/dist/identity.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* Identifies
|
|
2
|
+
* Machine identity keypair.
|
|
3
|
+
* Identifies a machine for access requests. It does not decrypt values.
|
|
4
4
|
*/
|
|
5
|
-
export type
|
|
5
|
+
export type MachineKeypair = {
|
|
6
6
|
publicKey: string;
|
|
7
7
|
privateKey: string;
|
|
8
8
|
};
|
|
9
|
-
export declare function
|
|
9
|
+
export declare function generateMachineIdentity(): MachineKeypair;
|
|
10
10
|
export declare function signAccessRequest(privateKeyB64: string, message: string): string;
|
|
11
11
|
export declare function verifyAccessRequest(publicKeyB64: string, message: string, signatureB64: string): boolean;
|
|
12
12
|
//# sourceMappingURL=identity.d.ts.map
|
package/dist/identity.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,wBAAgB,uBAAuB,IAAI,cAAc,CAOxD;AAED,wBAAgB,iBAAiB,CAC/B,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,GACd,MAAM,CAIR;AAED,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,GACnB,OAAO,CAUT"}
|
package/dist/identity.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ed25519 } from "@noble/curves/ed25519.js";
|
|
2
2
|
import { bytesToBase64, base64ToBytes, getRandomBytes, utf8Encode } from "./bytes.js";
|
|
3
|
-
export function
|
|
3
|
+
export function generateMachineIdentity() {
|
|
4
4
|
const privateKey = getRandomBytes(32);
|
|
5
5
|
const publicKey = ed25519.getPublicKey(privateKey);
|
|
6
6
|
return {
|
package/dist/identity.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAWtF,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAWtF,MAAM,UAAU,uBAAuB;IACrC,MAAM,UAAU,GAAG,cAAc,CAAC,EAAE,CAAC,CAAC;IACtC,MAAM,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;IACnD,OAAO;QACL,SAAS,EAAE,aAAa,CAAC,SAAS,CAAC;QACnC,UAAU,EAAE,aAAa,CAAC,UAAU,CAAC;KACtC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,aAAqB,EACrB,OAAe;IAEf,MAAM,UAAU,GAAG,aAAa,CAAC,aAAa,CAAC,CAAC;IAChD,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,CAAC;IAC1D,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,YAAoB,EACpB,OAAe,EACf,YAAoB;IAEpB,IAAI,CAAC;QACH,OAAO,OAAO,CAAC,MAAM,CACnB,aAAa,CAAC,YAAY,CAAC,EAC3B,UAAU,CAAC,OAAO,CAAC,EACnB,aAAa,CAAC,YAAY,CAAC,CAC5B,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -31,20 +31,31 @@ export type EncryptedSecretPayload = {
|
|
|
31
31
|
nonce: string;
|
|
32
32
|
ciphertext: string;
|
|
33
33
|
};
|
|
34
|
+
export declare const BACKUP_FORMAT_VERSION: 2;
|
|
35
|
+
export type BackupContext = {
|
|
36
|
+
slug: string;
|
|
37
|
+
name: string;
|
|
38
|
+
protection: "open" | "locked";
|
|
39
|
+
};
|
|
40
|
+
export type BackupValue = {
|
|
41
|
+
key: string;
|
|
42
|
+
/** Context slug. */
|
|
43
|
+
context: string;
|
|
44
|
+
expiresAt: string | null;
|
|
45
|
+
payload: EncryptedSecretPayload;
|
|
46
|
+
};
|
|
34
47
|
/** Portable encrypted backup envelope. */
|
|
35
48
|
export type EncryptedBackupEnvelope = {
|
|
36
49
|
format: "getmyenv-backup";
|
|
37
|
-
version: typeof
|
|
50
|
+
version: typeof BACKUP_FORMAT_VERSION;
|
|
38
51
|
createdAt: string;
|
|
39
52
|
projectName: string;
|
|
40
53
|
wrappedProjectKey: WrappedProjectKey;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
payload: EncryptedSecretPayload | null;
|
|
48
|
-
}>;
|
|
54
|
+
contexts: BackupContext[];
|
|
55
|
+
/** Every variable name in the project, including ones with no values. */
|
|
56
|
+
keys: string[];
|
|
57
|
+
/** Key name -> tag, for tagged keys only. Absent when nothing is tagged. */
|
|
58
|
+
tags?: Record<string, string>;
|
|
59
|
+
values: BackupValue[];
|
|
49
60
|
};
|
|
50
61
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,eAAO,MAAM,qBAAqB,EAAG,CAAU,CAAC;AAChD,eAAO,MAAM,SAAS,EAAG,aAAsB,CAAC;AAChD,eAAO,MAAM,GAAG,EAAG,UAAmB,CAAC;AAEvC,wDAAwD;AACxD,eAAO,MAAM,kBAAkB;;;;;CAKrB,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,wEAAwE;AACxE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,OAAO,EAAE,OAAO,qBAAqB,CAAC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,GAAG,EAAE,OAAO,GAAG,CAAC;IAChB,SAAS,EAAE,SAAS,CAAC;CACtB,CAAC;AAEF,sCAAsC;AACtC,MAAM,MAAM,sBAAsB,GAAG;IACnC,OAAO,EAAE,OAAO,qBAAqB,CAAC;IACtC,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,eAAO,MAAM,qBAAqB,EAAG,CAAU,CAAC;AAChD,eAAO,MAAM,SAAS,EAAG,aAAsB,CAAC;AAChD,eAAO,MAAM,GAAG,EAAG,UAAmB,CAAC;AAEvC,wDAAwD;AACxD,eAAO,MAAM,kBAAkB;;;;;CAKrB,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,wEAAwE;AACxE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,OAAO,EAAE,OAAO,qBAAqB,CAAC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,GAAG,EAAE,OAAO,GAAG,CAAC;IAChB,SAAS,EAAE,SAAS,CAAC;CACtB,CAAC;AAEF,sCAAsC;AACtC,MAAM,MAAM,sBAAsB,GAAG;IACnC,OAAO,EAAE,OAAO,qBAAqB,CAAC;IACtC,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAG,CAAU,CAAC;AAEhD,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,GAAG,QAAQ,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,oBAAoB;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,sBAAsB,CAAC;CACjC,CAAC;AAEF,0CAA0C;AAC1C,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,OAAO,EAAE,OAAO,qBAAqB,CAAC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,yEAAyE;IACzE,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB,CAAC"}
|
package/dist/types.js
CHANGED
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAU,CAAC;AAChD,MAAM,CAAC,MAAM,SAAS,GAAG,aAAsB,CAAC;AAChD,MAAM,CAAC,MAAM,GAAG,GAAG,UAAmB,CAAC;AAEvC,wDAAwD;AACxD,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,MAAM,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM;IACzB,UAAU,EAAE,CAAC;IACb,WAAW,EAAE,CAAC;IACd,UAAU,EAAE,EAAE;CACN,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAU,CAAC;AAChD,MAAM,CAAC,MAAM,SAAS,GAAG,aAAsB,CAAC;AAChD,MAAM,CAAC,MAAM,GAAG,GAAG,UAAmB,CAAC;AAEvC,wDAAwD;AACxD,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,MAAM,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM;IACzB,UAAU,EAAE,CAAC;IACb,WAAW,EAAE,CAAC;IACd,UAAU,EAAE,EAAE;CACN,CAAC;AA2BX,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAU,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@getmyenv/crypto",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Envelope encryption for getmyenv (Argon2id + AES-256-GCM)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
8
8
|
"files": [
|
|
9
9
|
"dist",
|
|
10
|
+
"!dist/**/*.test.*",
|
|
10
11
|
"README.md",
|
|
11
12
|
"LICENSE"
|
|
12
13
|
],
|
|
@@ -38,6 +39,7 @@
|
|
|
38
39
|
"vitest": "^4.1.11"
|
|
39
40
|
},
|
|
40
41
|
"scripts": {
|
|
42
|
+
"prebuild": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
41
43
|
"build": "tsc -p tsconfig.json",
|
|
42
44
|
"dev": "tsc -p tsconfig.json --watch",
|
|
43
45
|
"test": "vitest run",
|
package/dist/envelope.test.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"envelope.test.d.ts","sourceRoot":"","sources":["../src/envelope.test.ts"],"names":[],"mappings":""}
|
package/dist/envelope.test.js
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { createWrappedProjectKey, unwrapProjectKey, rewrapProjectKey, encryptSecret, decryptSecret, createBackupEnvelope, parseBackup, serializeBackup, restoreSecretsFromBackup, generateDevelopmentIdentity, signAccessRequest, verifyAccessRequest, } from "./index.js";
|
|
3
|
-
describe("envelope encryption", () => {
|
|
4
|
-
it("encrypts and decrypts a secret with PEK", async () => {
|
|
5
|
-
const { pek, wrapped } = await createWrappedProjectKey("test-vault-password");
|
|
6
|
-
const payload = encryptSecret(pek, "sk-live-example");
|
|
7
|
-
expect(payload.version).toBe(1);
|
|
8
|
-
expect(decryptSecret(pek, payload)).toBe("sk-live-example");
|
|
9
|
-
const unwrapped = await unwrapProjectKey("test-vault-password", wrapped);
|
|
10
|
-
expect(decryptSecret(unwrapped, payload)).toBe("sk-live-example");
|
|
11
|
-
});
|
|
12
|
-
it("rewraps PEK on password change without re-encrypting secrets", async () => {
|
|
13
|
-
const { pek, wrapped } = await createWrappedProjectKey("old-password");
|
|
14
|
-
const payload = encryptSecret(pek, "DATABASE_URL=postgres://...");
|
|
15
|
-
const rewrapped = await rewrapProjectKey("old-password", "new-password", wrapped);
|
|
16
|
-
const newPek = await unwrapProjectKey("new-password", rewrapped);
|
|
17
|
-
expect(decryptSecret(newPek, payload)).toBe("DATABASE_URL=postgres://...");
|
|
18
|
-
});
|
|
19
|
-
it("rejects wrong password", async () => {
|
|
20
|
-
const { wrapped } = await createWrappedProjectKey("correct");
|
|
21
|
-
await expect(unwrapProjectKey("wrong", wrapped)).rejects.toThrow();
|
|
22
|
-
});
|
|
23
|
-
});
|
|
24
|
-
describe("backup", () => {
|
|
25
|
-
it("creates portable encrypted backup and restores", async () => {
|
|
26
|
-
const { pek, wrapped } = await createWrappedProjectKey("backup-pass");
|
|
27
|
-
const payload = encryptSecret(pek, "secret-value");
|
|
28
|
-
const envelope = createBackupEnvelope({
|
|
29
|
-
projectName: "my-app",
|
|
30
|
-
wrappedProjectKey: wrapped,
|
|
31
|
-
secrets: [
|
|
32
|
-
{
|
|
33
|
-
name: "API_KEY",
|
|
34
|
-
environment: "Development",
|
|
35
|
-
status: "active",
|
|
36
|
-
expiresAt: null,
|
|
37
|
-
payload,
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
name: "PENDING_KEY",
|
|
41
|
-
environment: "Production",
|
|
42
|
-
status: "placeholder",
|
|
43
|
-
expiresAt: null,
|
|
44
|
-
payload: null,
|
|
45
|
-
},
|
|
46
|
-
],
|
|
47
|
-
});
|
|
48
|
-
const raw = serializeBackup(envelope);
|
|
49
|
-
const parsed = parseBackup(raw);
|
|
50
|
-
const restored = await restoreSecretsFromBackup("backup-pass", parsed);
|
|
51
|
-
expect(restored[0]?.value).toBe("secret-value");
|
|
52
|
-
expect(restored[1]?.status).toBe("placeholder");
|
|
53
|
-
expect(restored[1]?.value).toBe("");
|
|
54
|
-
expect(raw).not.toContain("secret-value");
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
describe("development identity", () => {
|
|
58
|
-
it("signs and verifies access requests", () => {
|
|
59
|
-
const id = generateDevelopmentIdentity();
|
|
60
|
-
const msg = "request:abc:project:env";
|
|
61
|
-
const sig = signAccessRequest(id.privateKey, msg);
|
|
62
|
-
expect(verifyAccessRequest(id.publicKey, msg, sig)).toBe(true);
|
|
63
|
-
expect(verifyAccessRequest(id.publicKey, "tampered", sig)).toBe(false);
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
//# sourceMappingURL=envelope.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"envelope.test.js","sourceRoot":"","sources":["../src/envelope.test.ts"],"names":[],"mappings":"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"}
|