credkeep 0.1.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 +21 -0
- package/README.md +47 -0
- package/dist/audit.d.ts +23 -0
- package/dist/audit.js +29 -0
- package/dist/audit.js.map +1 -0
- package/dist/canary.d.ts +30 -0
- package/dist/canary.js +44 -0
- package/dist/canary.js.map +1 -0
- package/dist/chain.d.ts +26 -0
- package/dist/chain.js +117 -0
- package/dist/chain.js.map +1 -0
- package/dist/cipher.d.ts +26 -0
- package/dist/cipher.js +103 -0
- package/dist/cipher.js.map +1 -0
- package/dist/credentials.d.ts +90 -0
- package/dist/credentials.js +252 -0
- package/dist/credentials.js.map +1 -0
- package/dist/env-store.d.ts +55 -0
- package/dist/env-store.js +213 -0
- package/dist/env-store.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/passwords.d.ts +2 -0
- package/dist/passwords.js +19 -0
- package/dist/passwords.js.map +1 -0
- package/dist/secrets.d.ts +17 -0
- package/dist/secrets.js +37 -0
- package/dist/secrets.js.map +1 -0
- package/dist/tail.d.ts +4 -0
- package/dist/tail.js +56 -0
- package/dist/tail.js.map +1 -0
- package/dist/totp.d.ts +24 -0
- package/dist/totp.js +111 -0
- package/dist/totp.js.map +1 -0
- package/package.json +61 -0
package/dist/secrets.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** A key in camelCase (`cardCvv`) → `SECRET_CARD_CVV` in the environment, under the app's prefix. */
|
|
2
|
+
export function envSecrets(env = process.env, prefix = "SECRET_") {
|
|
3
|
+
return {
|
|
4
|
+
async get(key) {
|
|
5
|
+
const name = `${prefix}${key
|
|
6
|
+
.replace(/([a-z0-9])([A-Z])/g, "$1_$2")
|
|
7
|
+
.replace(/[^a-zA-Z0-9]+/g, "_")
|
|
8
|
+
.toUpperCase()}`;
|
|
9
|
+
const value = env[name];
|
|
10
|
+
if (!value)
|
|
11
|
+
throw new Error(`secret ${key}: set ${name}`);
|
|
12
|
+
return value;
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export function memorySecrets(values) {
|
|
17
|
+
return {
|
|
18
|
+
async get(key) {
|
|
19
|
+
const v = values[key];
|
|
20
|
+
if (v === undefined)
|
|
21
|
+
throw new Error(`secret ${key}: not set`);
|
|
22
|
+
return v;
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export function trackingSecrets(source) {
|
|
27
|
+
const keys = new Map();
|
|
28
|
+
return {
|
|
29
|
+
async get(key) {
|
|
30
|
+
const value = await source.get(key);
|
|
31
|
+
keys.set(value, key);
|
|
32
|
+
return value;
|
|
33
|
+
},
|
|
34
|
+
keyOf: (value) => keys.get(value) ?? null,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=secrets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets.js","sourceRoot":"","sources":["../src/secrets.ts"],"names":[],"mappings":"AASA,qGAAqG;AACrG,MAAM,UAAU,UAAU,CAAC,MAAyB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS;IACjF,OAAO;QACL,KAAK,CAAC,GAAG,CAAC,GAAG;YACX,MAAM,IAAI,GAAG,GAAG,MAAM,GAAG,GAAG;iBACzB,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC;iBACtC,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC;iBAC9B,WAAW,EAAE,EAAE,CAAC;YACnB,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;YACxB,IAAI,CAAC,KAAK;gBAAE,MAAM,IAAI,KAAK,CAAC,UAAU,GAAG,SAAS,IAAI,EAAE,CAAC,CAAC;YAC1D,OAAO,KAAK,CAAC;QACf,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAA8B;IAC1D,OAAO;QACL,KAAK,CAAC,GAAG,CAAC,GAAG;YACX,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;YACtB,IAAI,CAAC,KAAK,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,UAAU,GAAG,WAAW,CAAC,CAAC;YAC/D,OAAO,CAAC,CAAC;QACX,CAAC;KACF,CAAC;AACJ,CAAC;AAQD,MAAM,UAAU,eAAe,CAAC,MAAoB;IAClD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAkB,CAAC;IACvC,OAAO;QACL,KAAK,CAAC,GAAG,CAAC,GAAG;YACX,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACpC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YACrB,OAAO,KAAK,CAAC;QACf,CAAC;QACD,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI;KAC1C,CAAC;AACJ,CAAC"}
|
package/dist/tail.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** The last `n` non-empty lines of `path`, oldest first; [] for a missing file. */
|
|
2
|
+
export declare function tailLines(path: string, n: number): Promise<string[]>;
|
|
3
|
+
/** Each of the last `n` lines parsed as JSON; a torn line is skipped. */
|
|
4
|
+
export declare function tailJson<T>(path: string, n: number): Promise<T[]>;
|
package/dist/tail.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The last lines of an append-only file, read from its end in blocks: a
|
|
3
|
+
* ledger that grows for months costs the same to consult as a fresh one.
|
|
4
|
+
*/
|
|
5
|
+
import { open } from "node:fs/promises";
|
|
6
|
+
const BLOCK = 64 * 1024;
|
|
7
|
+
/** The last `n` non-empty lines of `path`, oldest first; [] for a missing file. */
|
|
8
|
+
export async function tailLines(path, n) {
|
|
9
|
+
if (n <= 0)
|
|
10
|
+
return [];
|
|
11
|
+
let fh;
|
|
12
|
+
try {
|
|
13
|
+
fh = await open(path, "r");
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
const { size } = await fh.stat();
|
|
20
|
+
const chunks = [];
|
|
21
|
+
let pos = size;
|
|
22
|
+
let newlines = 0;
|
|
23
|
+
// Stop once the read-back text holds n+1 line breaks: the first partial line is then cut whole.
|
|
24
|
+
while (pos > 0 && newlines <= n) {
|
|
25
|
+
const len = Math.min(BLOCK, pos);
|
|
26
|
+
pos -= len;
|
|
27
|
+
const buf = Buffer.alloc(len);
|
|
28
|
+
await fh.read(buf, 0, len, pos);
|
|
29
|
+
chunks.unshift(buf);
|
|
30
|
+
for (let i = 0; i < len; i++)
|
|
31
|
+
if (buf[i] === 10)
|
|
32
|
+
newlines++;
|
|
33
|
+
}
|
|
34
|
+
// With n+1 line breaks in hand the last n lines are whole; the window's first line may be a
|
|
35
|
+
// fragment and is the one `slice(-n)` leaves behind.
|
|
36
|
+
const lines = Buffer.concat(chunks).toString("utf8").split("\n").filter(Boolean);
|
|
37
|
+
return lines.slice(-n);
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
await fh.close();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/** Each of the last `n` lines parsed as JSON; a torn line is skipped. */
|
|
44
|
+
export async function tailJson(path, n) {
|
|
45
|
+
const out = [];
|
|
46
|
+
for (const l of await tailLines(path, n)) {
|
|
47
|
+
try {
|
|
48
|
+
out.push(JSON.parse(l));
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// a line still being written, or a fragment at the window's start
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return out;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=tail.js.map
|
package/dist/tail.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tail.js","sourceRoot":"","sources":["../src/tail.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC,MAAM,KAAK,GAAG,EAAE,GAAG,IAAI,CAAC;AAExB,mFAAmF;AACnF,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAY,EAAE,CAAS;IACrD,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACtB,IAAI,EAAoC,CAAC;IACzC,IAAI,CAAC;QACH,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,CAAC;QACH,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;QACjC,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,IAAI,GAAG,GAAG,IAAI,CAAC;QACf,IAAI,QAAQ,GAAG,CAAC,CAAC;QACjB,gGAAgG;QAChG,OAAO,GAAG,GAAG,CAAC,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC;YAChC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YACjC,GAAG,IAAI,GAAG,CAAC;YACX,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC9B,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;YAChC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE;gBAAE,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE;oBAAE,QAAQ,EAAE,CAAC;QAC9D,CAAC;QACD,4FAA4F;QAC5F,qDAAqD;QACrD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACjF,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACzB,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;IACnB,CAAC;AACH,CAAC;AAED,yEAAyE;AACzE,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAI,IAAY,EAAE,CAAS;IACvD,MAAM,GAAG,GAAQ,EAAE,CAAC;IACpB,KAAK,MAAM,CAAC,IAAI,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;QACzC,IAAI,CAAC;YACH,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAM,CAAC,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,kEAAkE;QACpE,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
package/dist/totp.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare function base32Decode(text: string): Buffer;
|
|
2
|
+
export type TotpAlgorithm = "sha1" | "sha256" | "sha512";
|
|
3
|
+
export interface TotpOptions {
|
|
4
|
+
/** Unix ms; defaults to now. */
|
|
5
|
+
at?: number;
|
|
6
|
+
period?: number;
|
|
7
|
+
digits?: number;
|
|
8
|
+
algorithm?: TotpAlgorithm;
|
|
9
|
+
}
|
|
10
|
+
/** The code for `secret` (base32) at `at`. */
|
|
11
|
+
export declare function totp(secret: string, opts?: TotpOptions): string;
|
|
12
|
+
/** Milliseconds until the current code rolls over; wait it out when a site rejects a code that is about to expire. */
|
|
13
|
+
export declare function totpRemainingMs(at?: number, period?: number): number;
|
|
14
|
+
export interface TotpParams {
|
|
15
|
+
secret: string;
|
|
16
|
+
issuer: string | null;
|
|
17
|
+
account: string | null;
|
|
18
|
+
digits: number;
|
|
19
|
+
period: number;
|
|
20
|
+
algorithm: TotpAlgorithm;
|
|
21
|
+
}
|
|
22
|
+
export declare function parseOtpauth(uri: string): TotpParams;
|
|
23
|
+
/** The seed in page text or HTML: a URI wins, then a manual-entry key. Null when neither is there. */
|
|
24
|
+
export declare function findTotpSecret(text: string): string | null;
|
package/dist/totp.js
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TOTP (RFC 6238) with node:crypto, no dependency: the codes an
|
|
3
|
+
* authenticator app would show, so a login's second factor is ours to
|
|
4
|
+
* type. `findTotpSecret` pulls the seed out of an enrollment page (the
|
|
5
|
+
* otpauth:// link behind the QR, or the "enter this key manually" text).
|
|
6
|
+
*/
|
|
7
|
+
import { createHmac } from "node:crypto";
|
|
8
|
+
const ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
|
9
|
+
export function base32Decode(text) {
|
|
10
|
+
const clean = text.toUpperCase().replace(/[\s=-]/g, "");
|
|
11
|
+
let bits = 0;
|
|
12
|
+
let value = 0;
|
|
13
|
+
const out = [];
|
|
14
|
+
for (const ch of clean) {
|
|
15
|
+
const idx = ALPHABET.indexOf(ch);
|
|
16
|
+
if (idx < 0)
|
|
17
|
+
throw new Error(`base32: bad character ${JSON.stringify(ch)}`);
|
|
18
|
+
value = (value << 5) | idx;
|
|
19
|
+
bits += 5;
|
|
20
|
+
if (bits >= 8) {
|
|
21
|
+
out.push((value >>> (bits - 8)) & 0xff);
|
|
22
|
+
bits -= 8;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return Buffer.from(out);
|
|
26
|
+
}
|
|
27
|
+
/** The code for `secret` (base32) at `at`. */
|
|
28
|
+
export function totp(secret, opts = {}) {
|
|
29
|
+
const period = opts.period ?? 30;
|
|
30
|
+
const digits = opts.digits ?? 6;
|
|
31
|
+
const counter = Math.floor((opts.at ?? Date.now()) / 1000 / period);
|
|
32
|
+
const msg = Buffer.alloc(8);
|
|
33
|
+
msg.writeBigUInt64BE(BigInt(counter));
|
|
34
|
+
const mac = createHmac(opts.algorithm ?? "sha1", base32Decode(secret))
|
|
35
|
+
.update(msg)
|
|
36
|
+
.digest();
|
|
37
|
+
const offset = (mac[mac.length - 1] ?? 0) & 0x0f;
|
|
38
|
+
const code = (mac.readUInt32BE(offset) & 0x7fffffff) % 10 ** digits;
|
|
39
|
+
return String(code).padStart(digits, "0");
|
|
40
|
+
}
|
|
41
|
+
/** Milliseconds until the current code rolls over; wait it out when a site rejects a code that is about to expire. */
|
|
42
|
+
export function totpRemainingMs(at = Date.now(), period = 30) {
|
|
43
|
+
const step = period * 1000;
|
|
44
|
+
return step - (at % step);
|
|
45
|
+
}
|
|
46
|
+
export function parseOtpauth(uri) {
|
|
47
|
+
const u = new URL(uri);
|
|
48
|
+
if (u.protocol !== "otpauth:" || u.host !== "totp")
|
|
49
|
+
throw new Error("not an otpauth://totp URI");
|
|
50
|
+
const secret = u.searchParams.get("secret");
|
|
51
|
+
if (!secret)
|
|
52
|
+
throw new Error("otpauth URI has no secret");
|
|
53
|
+
const label = decodeURIComponent(u.pathname.replace(/^\/+/, ""));
|
|
54
|
+
const [labelIssuer, account] = label.includes(":") ? label.split(":", 2) : [null, label];
|
|
55
|
+
const algo = (u.searchParams.get("algorithm") ?? "SHA1").toLowerCase();
|
|
56
|
+
return {
|
|
57
|
+
secret: secret.replace(/[\s=-]/g, "").toUpperCase(),
|
|
58
|
+
issuer: u.searchParams.get("issuer") ?? labelIssuer,
|
|
59
|
+
account: account || null,
|
|
60
|
+
digits: Number(u.searchParams.get("digits") ?? 6),
|
|
61
|
+
period: Number(u.searchParams.get("period") ?? 30),
|
|
62
|
+
algorithm: algo === "sha256" || algo === "sha512" ? algo : "sha1",
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
const OTPAUTH = /otpauth:\/\/totp\/[^\s"'<>]+/i;
|
|
66
|
+
/**
|
|
67
|
+
* 16+ base32 characters in one case, optionally in spaced or dashed groups
|
|
68
|
+
* of 4. One case because a page prints its key in one case, and the words
|
|
69
|
+
* around it ("Make sure Time based") are mixed: they must not join the run.
|
|
70
|
+
*/
|
|
71
|
+
const MANUAL_KEYS = [
|
|
72
|
+
/\b(?:[a-z2-7]{4}[\s-]?){4,}[a-z2-7]*\b/g,
|
|
73
|
+
/\b(?:[A-Z2-7]{4}[\s-]?){4,}[A-Z2-7]*\b/g,
|
|
74
|
+
];
|
|
75
|
+
/**
|
|
76
|
+
* Seed lengths sites hand out, most common first (Google/Cloudflare 32,
|
|
77
|
+
* GitHub/Microsoft 16, AWS 64). A run is cut to the first of these some
|
|
78
|
+
* prefix of its groups adds up to, so a 4-letter word after the key
|
|
79
|
+
* ("then") does not join it. A wrong cut fails the confirm step, nothing worse.
|
|
80
|
+
*/
|
|
81
|
+
const SEED_LENGTHS = [32, 16, 64, 26, 52, 20, 24, 40];
|
|
82
|
+
function manualKey(text) {
|
|
83
|
+
for (const re of MANUAL_KEYS)
|
|
84
|
+
for (const m of text.matchAll(re)) {
|
|
85
|
+
const tokens = m[0].trim().split(/[\s-]+/);
|
|
86
|
+
const prefixes = tokens.map((_, i) => tokens.slice(0, i + 1).join(""));
|
|
87
|
+
for (const len of SEED_LENGTHS) {
|
|
88
|
+
const key = prefixes.find((p) => p.length === len);
|
|
89
|
+
if (key)
|
|
90
|
+
return key.toUpperCase();
|
|
91
|
+
}
|
|
92
|
+
const whole = tokens.join("");
|
|
93
|
+
if (whole.length >= 16 && whole.length % 2 === 0)
|
|
94
|
+
return whole.toUpperCase();
|
|
95
|
+
}
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
/** The seed in page text or HTML: a URI wins, then a manual-entry key. Null when neither is there. */
|
|
99
|
+
export function findTotpSecret(text) {
|
|
100
|
+
const uri = text.match(OTPAUTH);
|
|
101
|
+
if (uri) {
|
|
102
|
+
try {
|
|
103
|
+
return parseOtpauth(uri[0].replace(/&/g, "&")).secret;
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// fall through to a manual key
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return manualKey(text);
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=totp.js.map
|
package/dist/totp.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"totp.js","sourceRoot":"","sources":["../src/totp.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,QAAQ,GAAG,kCAAkC,CAAC;AAEpD,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IACxD,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,EAAE,IAAI,KAAK,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACjC,IAAI,GAAG,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAC5E,KAAK,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC;QAC3B,IAAI,IAAI,CAAC,CAAC;QACV,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;YACd,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;YACxC,IAAI,IAAI,CAAC,CAAC;QACZ,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC;AAYD,8CAA8C;AAC9C,MAAM,UAAU,IAAI,CAAC,MAAc,EAAE,OAAoB,EAAE;IACzD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;IACjC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;IAChC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,GAAG,MAAM,CAAC,CAAC;IACpE,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC5B,GAAG,CAAC,gBAAgB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IACtC,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,SAAS,IAAI,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;SACnE,MAAM,CAAC,GAAG,CAAC;SACX,MAAM,EAAE,CAAC;IACZ,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;IACjD,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC,GAAG,EAAE,IAAI,MAAM,CAAC;IACpE,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAC5C,CAAC;AAED,sHAAsH;AACtH,MAAM,UAAU,eAAe,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,MAAM,GAAG,EAAE;IAC1D,MAAM,IAAI,GAAG,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,IAAI,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;AAC5B,CAAC;AAWD,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,IAAI,CAAC,CAAC,QAAQ,KAAK,UAAU,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IACjG,MAAM,MAAM,GAAG,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC5C,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC1D,MAAM,KAAK,GAAG,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;IACjE,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACzF,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;IACvE,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE;QACnD,MAAM,EAAE,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,WAAW;QACnD,OAAO,EAAE,OAAO,IAAI,IAAI;QACxB,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACjD,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QAClD,SAAS,EAAE,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM;KAClE,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,GAAG,+BAA+B,CAAC;AAChD;;;;GAIG;AACH,MAAM,WAAW,GAAG;IAClB,yCAAyC;IACzC,yCAAyC;CAC1C,CAAC;AACF;;;;;GAKG;AACH,MAAM,YAAY,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;AAEtD,SAAS,SAAS,CAAC,IAAY;IAC7B,KAAK,MAAM,EAAE,IAAI,WAAW;QAC1B,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;YAClC,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC3C,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YACvE,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;gBAC/B,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC;gBACnD,IAAI,GAAG;oBAAE,OAAO,GAAG,CAAC,WAAW,EAAE,CAAC;YACpC,CAAC;YACD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC9B,IAAI,KAAK,CAAC,MAAM,IAAI,EAAE,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC;gBAAE,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC;QAC/E,CAAC;IACH,OAAO,IAAI,CAAC;AACd,CAAC;AAED,sGAAsG;AACtG,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAChC,IAAI,GAAG,EAAE,CAAC;QACR,IAAI,CAAC;YACH,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;QAC5D,CAAC;QAAC,MAAM,CAAC;YACP,+BAA+B;QACjC,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "credkeep",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"packageManager": "pnpm@9.15.0",
|
|
5
|
+
"description": "Keep the credentials an automation signs in with: sealed at rest, shared through SSM, every use audited, expiries watched.",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"main": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"README.md"
|
|
19
|
+
],
|
|
20
|
+
"engines": {
|
|
21
|
+
"node": ">=22"
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "node scripts/clean.mjs && tsc -p tsconfig.build.json",
|
|
25
|
+
"prepare": "pnpm build",
|
|
26
|
+
"typecheck": "tsc --noEmit",
|
|
27
|
+
"test": "vitest run src",
|
|
28
|
+
"lint": "biome check .",
|
|
29
|
+
"prepublishOnly": "pnpm lint && pnpm typecheck && pnpm test"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@aws-sdk/client-ssm": "3.1136.0",
|
|
33
|
+
"zod": "4.6.5"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@biomejs/biome": "2.5.14",
|
|
37
|
+
"@types/node": "22.20.3",
|
|
38
|
+
"typescript": "5.9.3",
|
|
39
|
+
"vitest": "5.0.1"
|
|
40
|
+
},
|
|
41
|
+
"repository": {
|
|
42
|
+
"type": "git",
|
|
43
|
+
"url": "git+https://github.com/wrenautomation/credkeep.git"
|
|
44
|
+
},
|
|
45
|
+
"homepage": "https://github.com/wrenautomation/credkeep#readme",
|
|
46
|
+
"bugs": {
|
|
47
|
+
"url": "https://github.com/wrenautomation/credkeep/issues"
|
|
48
|
+
},
|
|
49
|
+
"keywords": [
|
|
50
|
+
"credentials",
|
|
51
|
+
"secrets",
|
|
52
|
+
"vault",
|
|
53
|
+
"ssm",
|
|
54
|
+
"totp",
|
|
55
|
+
"keychain",
|
|
56
|
+
"audit"
|
|
57
|
+
],
|
|
58
|
+
"publishConfig": {
|
|
59
|
+
"access": "public"
|
|
60
|
+
}
|
|
61
|
+
}
|