summaryrefslogtreecommitdiff
path: root/worker/secret.ts
diff options
context:
space:
mode:
Diffstat (limited to 'worker/secret.ts')
-rw-r--r--worker/secret.ts343
1 files changed, 183 insertions, 160 deletions
diff --git a/worker/secret.ts b/worker/secret.ts
index e0a4c5d..f5ae93f 100644
--- a/worker/secret.ts
+++ b/worker/secret.ts
@@ -1,36 +1,36 @@
import {
- Either,
- getRequiredEnvVars,
- getStdout,
- type IEither,
- type ITraceable,
- type LogMetricTraceSupplier,
- Metric,
- TraceUtil,
+ Either,
+ getRequiredEnvVars,
+ getStdout,
+ type IEither,
+ type ITraceable,
+ type LogMetricTraceSupplier,
+ Metric,
+ TraceUtil,
} from "@emprespresso/pengueno";
// -- <ISecret> --
export interface LoginItem {
- login: {
- username: string;
- password: string;
- };
+ login: {
+ username: string;
+ password: string;
+ };
}
export interface SecureNote {
- notes: string;
+ notes: string;
}
export type SecretItem = LoginItem | SecureNote;
export interface IVault<TClient, TKey, TItemId> {
- unlock: (client: TClient) => Promise<IEither<Error, TKey>>;
- lock: (client: TClient, key: TKey) => Promise<IEither<Error, TKey>>;
+ unlock: (client: TClient) => Promise<IEither<Error, TKey>>;
+ lock: (client: TClient, key: TKey) => Promise<IEither<Error, TKey>>;
- fetchSecret: <T extends SecretItem>(
- client: TClient,
- key: TKey,
- item: TItemId,
- ) => Promise<IEither<Error, T>>;
+ fetchSecret: <T extends SecretItem>(
+ client: TClient,
+ key: TKey,
+ item: TItemId,
+ ) => Promise<IEither<Error, T>>;
}
// -- </ISecret> --
@@ -39,155 +39,178 @@ type TClient = ITraceable<unknown, LogMetricTraceSupplier>;
type TKey = string;
type TItemId = string;
export class Bitwarden implements IVault<TClient, TKey, TItemId> {
- constructor(private readonly config: BitwardenConfig) {}
+ constructor(private readonly config: BitwardenConfig) {}
- public unlock(client: TClient) {
- return client
- .move(this.config)
- .bimap(TraceUtil.withMetricTrace(Bitwarden.loginMetric))
- .flatMap((tConfig) =>
- tConfig.move(`bw config server ${tConfig.get().server}`).map(getStdout),
- )
- .map(async (tEitherWithConfig) => {
- const eitherWithConfig = await tEitherWithConfig.get();
- tEitherWithConfig.trace.trace("logging in~ ^.^");
- return eitherWithConfig.flatMapAsync((_) =>
- tEitherWithConfig
- .move("bw login --apikey --quiet")
- .map(getStdout)
- .get(),
- );
- })
- .peek(async (tEitherWithAuthd) => {
- const eitherWithAuthd = await tEitherWithAuthd.get();
- return tEitherWithAuthd.trace.trace(
- eitherWithAuthd.fold(
- (err, _val) => Bitwarden.loginMetric[err ? "failure" : "success"],
- ),
- );
- })
- .map(async (tEitherWithAuthd) => {
- const eitherWithAuthd = await tEitherWithAuthd.get();
- tEitherWithAuthd.trace.trace("unlocking the secret vault~ (◕ᴗ◕✿)");
- return eitherWithAuthd.flatMapAsync((_) =>
- tEitherWithAuthd
- .move("bw unlock --passwordenv BW_PASSWORD --raw")
- .map(getStdout)
- .get(),
- );
- })
- .peek(async (tEitherWithSession) => {
- const eitherWithAuthd = await tEitherWithSession.get();
- return tEitherWithSession.trace.trace(
- eitherWithAuthd.fold(
- (err, _val) =>
- Bitwarden.unlockVaultMetric[err ? "failure" : "success"],
- ),
- );
- })
- .get();
- }
+ public unlock(client: TClient) {
+ return client
+ .move(this.config)
+ .bimap(TraceUtil.withMetricTrace(Bitwarden.loginMetric))
+ .flatMap((tConfig) =>
+ tConfig
+ .move(`bw config server ${tConfig.get().server}`)
+ .map(getStdout),
+ )
+ .map(async (tEitherWithConfig) => {
+ const eitherWithConfig = await tEitherWithConfig.get();
+ tEitherWithConfig.trace.trace("logging in~ ^.^");
+ return eitherWithConfig.flatMapAsync((_) =>
+ tEitherWithConfig
+ .move("bw login --apikey --quiet")
+ .map(getStdout)
+ .get(),
+ );
+ })
+ .peek(async (tEitherWithAuthd) => {
+ const eitherWithAuthd = await tEitherWithAuthd.get();
+ return tEitherWithAuthd.trace.trace(
+ eitherWithAuthd.fold(
+ ({ isLeft }) =>
+ Bitwarden.loginMetric[
+ isLeft ? "failure" : "success"
+ ],
+ ),
+ );
+ })
+ .map(async (tEitherWithAuthd) => {
+ const eitherWithAuthd = await tEitherWithAuthd.get();
+ tEitherWithAuthd.trace.trace(
+ "unlocking the secret vault~ (◕ᴗ◕✿)",
+ );
+ return eitherWithAuthd.flatMapAsync((_) =>
+ tEitherWithAuthd
+ .move("bw unlock --passwordenv BW_PASSWORD --raw")
+ .map(getStdout)
+ .get(),
+ );
+ })
+ .peek(async (tEitherWithSession) => {
+ const eitherWithAuthd = await tEitherWithSession.get();
+ return tEitherWithSession.trace.trace(
+ eitherWithAuthd.fold(
+ ({ isLeft }) =>
+ Bitwarden.unlockVaultMetric[
+ isLeft ? "failure" : "success"
+ ],
+ ),
+ );
+ })
+ .get();
+ }
- public fetchSecret<T extends SecretItem>(
- client: TClient,
- key: string,
- item: string,
- ): Promise<IEither<Error, T>> {
- return client
- .move(key)
- .bimap(TraceUtil.withMetricTrace(Bitwarden.fetchSecretMetric))
- .peek((tSession) =>
- tSession.trace.trace(`looking for your secret ${item} (⑅˘꒳˘)`),
- )
- .flatMap((tSession) =>
- tSession
- .move("bw list items")
- .map((listCmd) =>
- getStdout(listCmd, { env: { BW_SESSION: tSession.get() } }),
- ),
- )
- .map(
- TraceUtil.promiseify((tEitherItemsJson) =>
- tEitherItemsJson
- .get()
- .flatMap(
- (itemsJson): IEither<Error, Array<T & { name: string }>> =>
- Either.fromFailable(() => JSON.parse(itemsJson)),
+ public fetchSecret<T extends SecretItem>(
+ client: TClient,
+ key: string,
+ item: string,
+ ): Promise<IEither<Error, T>> {
+ return client
+ .move(key)
+ .bimap(TraceUtil.withMetricTrace(Bitwarden.fetchSecretMetric))
+ .peek((tSession) =>
+ tSession.trace.trace(`looking for your secret ${item} (⑅˘꒳˘)`),
+ )
+ .flatMap((tSession) =>
+ tSession
+ .move("bw list items")
+ .map((listCmd) =>
+ getStdout(listCmd, {
+ env: { BW_SESSION: tSession.get() },
+ }),
+ ),
+ )
+ .map(
+ TraceUtil.promiseify((tEitherItemsJson) =>
+ tEitherItemsJson
+ .get()
+ .flatMap(
+ (
+ itemsJson,
+ ): IEither<Error, Array<T & { name: string }>> =>
+ Either.fromFailable(() =>
+ JSON.parse(itemsJson),
+ ),
+ )
+ .flatMap((itemsList): IEither<Error, T> => {
+ const secret = itemsList.find(
+ ({ name }) => name === item,
+ );
+ if (!secret) {
+ return Either.left(
+ new Error(
+ `couldn't find the item ${item} (。•́︿•̀。)`,
+ ),
+ );
+ }
+ return Either.right(secret);
+ }),
+ ),
)
- .flatMap((itemsList): IEither<Error, T> => {
- const secret = itemsList.find(({ name }) => name === item);
- if (!secret) {
- return Either.left(
- new Error(`couldn't find the item ${item} (。•́︿•̀。)`),
+ .peek(async (tEitherWithSecret) => {
+ const eitherWithSecret = await tEitherWithSecret.get();
+ return tEitherWithSecret.trace.trace(
+ eitherWithSecret.fold(
+ ({ isLeft }) =>
+ Bitwarden.fetchSecretMetric[
+ isLeft ? "failure" : "success"
+ ],
+ ),
);
- }
- return Either.right(secret);
- }),
- ),
- )
- .peek(async (tEitherWithSecret) => {
- const eitherWithSecret = await tEitherWithSecret.get();
- return tEitherWithSecret.trace.trace(
- eitherWithSecret.fold(
- (err, _val) =>
- Bitwarden.fetchSecretMetric[err ? "failure" : "success"],
- ),
- );
- })
- .get();
- }
+ })
+ .get();
+ }
- public lock(client: TClient, key: TKey) {
- return client
- .move(key)
- .bimap(TraceUtil.withMetricTrace(Bitwarden.lockVaultMetric))
- .peek((tSession) =>
- tSession.trace.trace(`taking care of locking the vault :3`),
- )
- .flatMap((tSession) =>
- tSession
- .move("bw lock")
- .map((lockCmd) =>
- getStdout(lockCmd, { env: { BW_SESSION: tSession.get() } }),
- ),
- )
- .peek(async (tEitherWithLocked) => {
- const eitherWithLocked = await tEitherWithLocked.get();
- return eitherWithLocked.fold((err, _val) => {
- tEitherWithLocked.trace.trace(
- Bitwarden.lockVaultMetric[err ? "failure" : "success"],
- );
- if (err) return;
- tEitherWithLocked.trace.trace(
- "all locked up and secure now~ (。•̀ᴗ-)✧",
- );
- });
- })
- .get();
- }
+ public lock(client: TClient, key: TKey) {
+ return client
+ .move(key)
+ .bimap(TraceUtil.withMetricTrace(Bitwarden.lockVaultMetric))
+ .peek((tSession) =>
+ tSession.trace.trace(`taking care of locking the vault :3`),
+ )
+ .flatMap((tSession) =>
+ tSession
+ .move("bw lock")
+ .map((lockCmd) =>
+ getStdout(lockCmd, {
+ env: { BW_SESSION: tSession.get() },
+ }),
+ ),
+ )
+ .peek(async (tEitherWithLocked) => {
+ const eitherWithLocked = await tEitherWithLocked.get();
+ return eitherWithLocked.fold(({ isLeft }) => {
+ tEitherWithLocked.trace.trace(
+ Bitwarden.lockVaultMetric[isLeft ? "failure" : "success"],
+ );
+ if (isLeft) return;
+ tEitherWithLocked.trace.trace(
+ "all locked up and secure now~ (。•̀ᴗ-)✧",
+ );
+ });
+ })
+ .get();
+ }
- public static getConfigFromEnvironment(): IEither<Error, BitwardenConfig> {
- return getRequiredEnvVars([
- "BW_SERVER",
- "BW_CLIENTSECRET",
- "BW_CLIENTID",
- "BW_PASSWORD",
- ]).mapRight(({ BW_SERVER, BW_CLIENTSECRET, BW_CLIENTID }) => ({
- clientId: BW_CLIENTID,
- secret: BW_CLIENTSECRET,
- server: BW_SERVER,
- }));
- }
+ public static getConfigFromEnvironment(): IEither<Error, BitwardenConfig> {
+ return getRequiredEnvVars([
+ "BW_SERVER",
+ "BW_CLIENTSECRET",
+ "BW_CLIENTID",
+ "BW_PASSWORD",
+ ]).mapRight(({ BW_SERVER, BW_CLIENTSECRET, BW_CLIENTID }) => ({
+ clientId: BW_CLIENTID,
+ secret: BW_CLIENTSECRET,
+ server: BW_SERVER,
+ }));
+ }
- private static loginMetric = Metric.fromName("Bitwarden.login");
- private static unlockVaultMetric = Metric.fromName("Bitwarden.unlockVault");
- private static fetchSecretMetric = Metric.fromName("Bitwarden.fetchSecret");
- private static lockVaultMetric = Metric.fromName("Bitwarden.lock");
+ private static loginMetric = Metric.fromName("Bitwarden.login");
+ private static unlockVaultMetric = Metric.fromName("Bitwarden.unlockVault");
+ private static fetchSecretMetric = Metric.fromName("Bitwarden.fetchSecret");
+ private static lockVaultMetric = Metric.fromName("Bitwarden.lock");
}
export interface BitwardenConfig {
- server: string;
- secret: string;
- clientId: string;
+ server: string;
+ secret: string;
+ clientId: string;
}
// -- </IVault> --