1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
import {
getRequiredEnv,
getStdout,
loggerWithPrefix,
type PrefixLogger,
} from "./mod.ts";
export class BitwardenSession {
private readonly sessionInitializer: Promise<string>;
private readonly logger: PrefixLogger;
constructor(
server = getRequiredEnv("BW_SERVER"),
logger = loggerWithPrefix(),
) {
["BW_CLIENTID", "BW_CLIENTSECRET"].forEach(getRequiredEnv);
const instanceId = crypto.randomUUID().split("-").at(0);
this.logger = logger.withAdditionalPrefix(() =>
`[BitwardenSession.instance.${instanceId}]`
);
this.sessionInitializer = getStdout(
`bw config server ${server} --quiet`,
)
.then(() => {
this.logger.log("logging in via api (˘ω˘)");
return getStdout(`bw login --apikey --quiet`);
})
.then(() => {
this.logger.log("unlocking the secret vault~ (◕ᴗ◕✿)");
return getStdout(`bw unlock --passwordenv BW_PASSWORD --raw`);
})
.then((session) => {
const _session = session.trim();
this.logger.log(`got my session key (>ᴗ<) ${_session}`);
return _session;
});
}
public async getItem<T extends LoginItem | SecureNote>(
secretName: string,
): Promise<T> {
this.logger.log(`looking for your secret ${secretName} (⑅˘꒳˘)`);
return await this.sessionInitializer.then((session) =>
getStdout(`bw list items`, {
env: {
BW_SESSION: session,
},
})
).then((items) => JSON.parse(items)).then((items) =>
items.find(({ name }: { name: string }) => name === secretName)
).then((item) => {
if (!item) {
throw new Error(
"couldn't find the bitwarden item " + secretName + " (。•́︿•̀。)",
);
}
this.logger.log(`yay! found secret: ${secretName} (*ˊᗜˋ*)`);
return item;
});
}
async close(): Promise<void> {
return await this.sessionInitializer.then((session) =>
getStdout(`bw lock`, { env: { BW_SESSION: session } })
).then(() => {
this.logger.log("all locked up and secure now~ (。•̀ᴗ-)✧");
});
}
}
export type LoginItem = {
login: {
username: string;
password: string;
};
};
export type SecureNote = {
notes: string;
};
|