@catladder/cli 1.142.2 → 1.143.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/dist/apps/cli/commands/cloudSQL/index.js +0 -1
- package/dist/apps/cli/commands/cloudSQL/index.js.map +1 -1
- package/dist/apps/cli/commands/general/index.js +0 -14
- package/dist/apps/cli/commands/general/index.js.map +1 -1
- package/dist/apps/cli/commands/project/index.js +0 -1
- package/dist/apps/cli/commands/project/index.js.map +1 -1
- package/dist/apps/cli/verify/index.js +4 -31
- package/dist/apps/cli/verify/index.js.map +1 -1
- package/dist/bundles/catenv/index.js +1 -1
- package/dist/bundles/cli/index.js +20 -282
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/apps/cli/commands/cloudSQL/index.ts +0 -1
- package/src/apps/cli/commands/general/index.ts +0 -6
- package/src/apps/cli/commands/project/index.ts +0 -1
- package/src/apps/cli/verify/index.ts +1 -17
- package/dist/apps/cli/commands/project/commandInitProject.old.d.ts +0 -3
- package/dist/apps/cli/commands/project/commandInitProject.old.js +0 -345
- package/dist/apps/cli/commands/project/commandInitProject.old.js.map +0 -1
- package/dist/apps/cli/config/writeConfig.d.ts +0 -5
- package/dist/apps/cli/config/writeConfig.js +0 -106
- package/dist/apps/cli/config/writeConfig.js.map +0 -1
- package/dist/apps/cli/verify/migration/fromv2.d.ts +0 -4
- package/dist/apps/cli/verify/migration/fromv2.js +0 -349
- package/dist/apps/cli/verify/migration/fromv2.js.map +0 -1
- package/dist/apps/cli/verify/migration/migrateSecrets.d.ts +0 -4
- package/dist/apps/cli/verify/migration/migrateSecrets.js +0 -91
- package/dist/apps/cli/verify/migration/migrateSecrets.js.map +0 -1
- package/dist/apps/cli/verify/migration/oldGitlabCi.d.ts +0 -18
- package/dist/apps/cli/verify/migration/oldGitlabCi.js +0 -30
- package/dist/apps/cli/verify/migration/oldGitlabCi.js.map +0 -1
- package/dist/utils/passwordstore/index.d.ts +0 -7
- package/dist/utils/passwordstore/index.js +0 -315
- package/dist/utils/passwordstore/index.js.map +0 -1
- package/src/apps/cli/commands/project/commandInitProject.old.ts +0 -290
- package/src/apps/cli/config/writeConfig.ts +0 -71
- package/src/apps/cli/verify/migration/fromv2.ts +0 -262
- package/src/apps/cli/verify/migration/migrateSecrets.ts +0 -47
- package/src/apps/cli/verify/migration/oldGitlabCi.ts +0 -48
- package/src/utils/passwordstore/index.ts +0 -162
|
@@ -1,262 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
BuildConfig,
|
|
3
|
-
ComponentConfig,
|
|
4
|
-
Config,
|
|
5
|
-
DeployConfigKubernetes,
|
|
6
|
-
Env,
|
|
7
|
-
} from "@catladder/pipeline";
|
|
8
|
-
import {
|
|
9
|
-
existsSync,
|
|
10
|
-
lstatSync,
|
|
11
|
-
readdirSync,
|
|
12
|
-
readFile,
|
|
13
|
-
writeFile,
|
|
14
|
-
} from "fs-extra";
|
|
15
|
-
import { isEmpty } from "lodash";
|
|
16
|
-
import { join } from "path";
|
|
17
|
-
import type Vorpal from "vorpal";
|
|
18
|
-
import {
|
|
19
|
-
getGitlabCi,
|
|
20
|
-
getGitlabCiFilePath,
|
|
21
|
-
} from "../../../../config/getProjectConfig";
|
|
22
|
-
import { readYaml } from "../../../../utils/files";
|
|
23
|
-
import { syncBitwarden } from "../../../../utils/passwordstore";
|
|
24
|
-
import { getGitRoot } from "../../../../utils/projects";
|
|
25
|
-
import { writeConfig } from "../../config/writeConfig";
|
|
26
|
-
import { migrateSecrets } from "./migrateSecrets";
|
|
27
|
-
import type { OldGitlabCiFile } from "./oldGitlabCi";
|
|
28
|
-
import { detectBuildConfig, isOldInclude } from "./oldGitlabCi";
|
|
29
|
-
export const LEGACY_ENVS = [
|
|
30
|
-
"dev-local",
|
|
31
|
-
"dev",
|
|
32
|
-
"review",
|
|
33
|
-
"stage",
|
|
34
|
-
"prod",
|
|
35
|
-
] as const;
|
|
36
|
-
|
|
37
|
-
const arrayToRecord = (arr: { name: string }[]): Record<string, any> => {
|
|
38
|
-
if (!arr) return undefined;
|
|
39
|
-
if (!Array.isArray(arr)) return arr;
|
|
40
|
-
return Object.fromEntries(arr.map(({ name, ...rest }) => [name, rest]));
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
const transformVars = (rawVars: {
|
|
44
|
-
public: Record<string, any>;
|
|
45
|
-
secret: Record<string, any>;
|
|
46
|
-
fromCommponents: any;
|
|
47
|
-
}) => {
|
|
48
|
-
if (rawVars.fromCommponents) {
|
|
49
|
-
console.warn("cant transform legacy fromCommponents");
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return {
|
|
53
|
-
public: rawVars.public,
|
|
54
|
-
secret: rawVars.secret ? Object.keys(rawVars.secret) : undefined,
|
|
55
|
-
};
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
const getLegacyMonorepoSubCiFiles = (dir: string) => {
|
|
59
|
-
return readdirSync(dir)
|
|
60
|
-
.filter((file) => lstatSync(file).isDirectory())
|
|
61
|
-
.map((dir) => ({
|
|
62
|
-
dir,
|
|
63
|
-
ci: join(dir, ".gitlab-ci.yml"),
|
|
64
|
-
}))
|
|
65
|
-
.filter(({ ci }) => existsSync(ci));
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
const transformValues = (
|
|
69
|
-
valuesIn: Record<string, any>
|
|
70
|
-
): DeployConfigKubernetes["values"] => {
|
|
71
|
-
if (isEmpty(valuesIn)) {
|
|
72
|
-
return undefined;
|
|
73
|
-
}
|
|
74
|
-
delete valuesIn?.application?.host;
|
|
75
|
-
delete valuesIn?.application?.command;
|
|
76
|
-
|
|
77
|
-
return {
|
|
78
|
-
...valuesIn,
|
|
79
|
-
jobs: arrayToRecord(valuesIn?.jobs),
|
|
80
|
-
cronjobs: arrayToRecord(valuesIn?.cronjobs),
|
|
81
|
-
};
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
export const isV2 = async () => {
|
|
85
|
-
const gitlabCi = await getGitlabCi<OldGitlabCiFile>();
|
|
86
|
-
return isOldInclude(gitlabCi);
|
|
87
|
-
};
|
|
88
|
-
export const migrateV2 = async (vorpal: Vorpal) => {
|
|
89
|
-
const gitlabCi = await getGitlabCi<OldGitlabCiFile>();
|
|
90
|
-
const gitRoot = await getGitRoot();
|
|
91
|
-
|
|
92
|
-
const {
|
|
93
|
-
CUSTOMER_NAME,
|
|
94
|
-
APP_NAME,
|
|
95
|
-
COMPONENT_NAME = "web",
|
|
96
|
-
APP_DIR = ".",
|
|
97
|
-
STAGING_ENABLED,
|
|
98
|
-
} = gitlabCi.variables;
|
|
99
|
-
|
|
100
|
-
vorpal
|
|
101
|
-
.command("migrate")
|
|
102
|
-
|
|
103
|
-
.action(async function () {
|
|
104
|
-
this.log("");
|
|
105
|
-
this.log("⚠️ this project uses legacy catladder (v2)");
|
|
106
|
-
this.log("");
|
|
107
|
-
this.log(
|
|
108
|
-
"😼 I can migrate the project for you. This contains the following steps:"
|
|
109
|
-
);
|
|
110
|
-
this.log("");
|
|
111
|
-
this.log(
|
|
112
|
-
" - migrate the config from values-*.yml to catladder config file"
|
|
113
|
-
);
|
|
114
|
-
this.log(
|
|
115
|
-
" - migrate the secrets from bitwarden to gitlab (this will trash the entries in bitwarden)"
|
|
116
|
-
);
|
|
117
|
-
this.log("");
|
|
118
|
-
this.log(
|
|
119
|
-
"☝ make sure that you checked in your current state in case something goes wrong."
|
|
120
|
-
);
|
|
121
|
-
this.log(
|
|
122
|
-
"☝ secrets in bitwarden are deleted, but can be restored within 30 days."
|
|
123
|
-
);
|
|
124
|
-
this.log("");
|
|
125
|
-
const { shouldContinue } = await this.prompt({
|
|
126
|
-
default: true,
|
|
127
|
-
message: "Migrate project now? 🤔",
|
|
128
|
-
name: "shouldContinue",
|
|
129
|
-
type: "confirm",
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
if (shouldContinue) {
|
|
133
|
-
vorpal.log("");
|
|
134
|
-
vorpal.log("");
|
|
135
|
-
vorpal.log("💪😼 ok, let's go...");
|
|
136
|
-
vorpal.log("");
|
|
137
|
-
vorpal.log("");
|
|
138
|
-
|
|
139
|
-
const createComponent = async (
|
|
140
|
-
dir: string,
|
|
141
|
-
ciFile: OldGitlabCiFile
|
|
142
|
-
): Promise<ComponentConfig> => {
|
|
143
|
-
const { env, ...baseValues } =
|
|
144
|
-
(await readYaml(dir + "/values.yml")) ?? {};
|
|
145
|
-
|
|
146
|
-
const startCommand = Array.isArray(baseValues?.application?.command)
|
|
147
|
-
? baseValues?.application?.command.join(" ")
|
|
148
|
-
: baseValues?.application?.command;
|
|
149
|
-
return {
|
|
150
|
-
vars: env ? transformVars(env) : undefined,
|
|
151
|
-
dir: dir,
|
|
152
|
-
build: {
|
|
153
|
-
type: detectBuildConfig(ciFile),
|
|
154
|
-
startCommand: startCommand,
|
|
155
|
-
} as BuildConfig,
|
|
156
|
-
deploy: {
|
|
157
|
-
type: "kubernetes",
|
|
158
|
-
values: transformValues(baseValues),
|
|
159
|
-
cluster: {
|
|
160
|
-
type: "gcloud",
|
|
161
|
-
name: "ch-production",
|
|
162
|
-
projectId: "skynet-swiss",
|
|
163
|
-
region: "europe-west6-a",
|
|
164
|
-
domainCanonical: "panter.swiss",
|
|
165
|
-
},
|
|
166
|
-
},
|
|
167
|
-
env: await LEGACY_ENVS.reduce<Promise<Env>>(
|
|
168
|
-
async (acc, envName) => {
|
|
169
|
-
if (envName === "stage" && !STAGING_ENABLED) {
|
|
170
|
-
return {
|
|
171
|
-
...(await acc),
|
|
172
|
-
[envName]: false,
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
const newEnvName = envName === "dev-local" ? "local" : envName;
|
|
176
|
-
|
|
177
|
-
const envValues =
|
|
178
|
-
(await readYaml(dir + `/values-${envName}.yml`)) ?? {};
|
|
179
|
-
const { env, ...rest } = envValues;
|
|
180
|
-
const host = rest?.application?.host;
|
|
181
|
-
const values = transformValues(rest);
|
|
182
|
-
return {
|
|
183
|
-
...(await acc),
|
|
184
|
-
[newEnvName]: {
|
|
185
|
-
host: host,
|
|
186
|
-
vars: env ? transformVars(env) : undefined,
|
|
187
|
-
deploy: values
|
|
188
|
-
? {
|
|
189
|
-
values: values,
|
|
190
|
-
}
|
|
191
|
-
: undefined,
|
|
192
|
-
},
|
|
193
|
-
};
|
|
194
|
-
},
|
|
195
|
-
Promise.resolve({})
|
|
196
|
-
),
|
|
197
|
-
};
|
|
198
|
-
};
|
|
199
|
-
let components: Record<string, ComponentConfig>;
|
|
200
|
-
if (detectBuildConfig(gitlabCi) === "monorepo") {
|
|
201
|
-
components = await getLegacyMonorepoSubCiFiles(gitRoot).reduce<
|
|
202
|
-
Promise<Record<string, ComponentConfig>>
|
|
203
|
-
>(async (acc, el) => {
|
|
204
|
-
return {
|
|
205
|
-
...(await acc),
|
|
206
|
-
[el.dir]: await createComponent(el.dir, await readYaml(el.ci)),
|
|
207
|
-
};
|
|
208
|
-
}, Promise.resolve({}));
|
|
209
|
-
} else {
|
|
210
|
-
components = {
|
|
211
|
-
[COMPONENT_NAME]: await createComponent(APP_DIR, gitlabCi),
|
|
212
|
-
};
|
|
213
|
-
}
|
|
214
|
-
// we only have one component
|
|
215
|
-
const config: Config = {
|
|
216
|
-
customerName: CUSTOMER_NAME,
|
|
217
|
-
appName: APP_NAME,
|
|
218
|
-
components,
|
|
219
|
-
};
|
|
220
|
-
|
|
221
|
-
const comment =
|
|
222
|
-
"Old migrated config:\n\n" +
|
|
223
|
-
(await readFile(await getGitlabCiFilePath(), {
|
|
224
|
-
encoding: "utf-8",
|
|
225
|
-
}));
|
|
226
|
-
|
|
227
|
-
this.log("-------------------");
|
|
228
|
-
this.log("migrate config");
|
|
229
|
-
await writeConfig(this, config, {
|
|
230
|
-
endComment: comment,
|
|
231
|
-
});
|
|
232
|
-
this.log("write gitlab-ci.yml");
|
|
233
|
-
await writeFile(
|
|
234
|
-
await getGitlabCiFilePath(),
|
|
235
|
-
"include: https://git.panter.ch/api/v4/projects/catladder%2Fcatladder/packages/generic/ci-includes/main/gitlab-ci.yml",
|
|
236
|
-
{ encoding: "utf-8" }
|
|
237
|
-
);
|
|
238
|
-
|
|
239
|
-
this.log("-------------------");
|
|
240
|
-
this.log("migrate secrets");
|
|
241
|
-
await syncBitwarden();
|
|
242
|
-
for (const env of LEGACY_ENVS) {
|
|
243
|
-
if (env === "stage" && !STAGING_ENABLED) return;
|
|
244
|
-
await migrateSecrets(this, config, env);
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
this.log("-------------------");
|
|
248
|
-
|
|
249
|
-
this.log("done!");
|
|
250
|
-
this.log("");
|
|
251
|
-
this.log("You can remove the values*.yml files now.");
|
|
252
|
-
|
|
253
|
-
this.log("-------------------");
|
|
254
|
-
} else {
|
|
255
|
-
this.log(
|
|
256
|
-
"☝ if you want to use catladder in legacy mode, install @panter/catladder globally and invoke catladder-legacy"
|
|
257
|
-
);
|
|
258
|
-
}
|
|
259
|
-
});
|
|
260
|
-
|
|
261
|
-
vorpal.exec("migrate");
|
|
262
|
-
};
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import type { Config } from "@catladder/pipeline";
|
|
2
|
-
import { getEnvironment } from "@catladder/pipeline";
|
|
3
|
-
import { load } from "js-yaml";
|
|
4
|
-
import { pick } from "lodash";
|
|
5
|
-
import type { CommandInstance } from "vorpal";
|
|
6
|
-
import { upsertAllVariables } from "../../../../utils/gitlab";
|
|
7
|
-
import { readPass, trashItem } from "../../../../utils/passwordstore";
|
|
8
|
-
import type { LEGACY_ENVS } from "./fromv2";
|
|
9
|
-
|
|
10
|
-
const getPassPath = (newConfig: Config, env: string) => {
|
|
11
|
-
return `${newConfig.customerName}/${newConfig.appName}/${env}/secrets.yml`;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
export const migrateSecrets = async (
|
|
15
|
-
vorpal: CommandInstance,
|
|
16
|
-
newConfig: Config,
|
|
17
|
-
oldEnv: typeof LEGACY_ENVS[number]
|
|
18
|
-
) => {
|
|
19
|
-
const newEnv = oldEnv === "dev-local" ? "local" : oldEnv;
|
|
20
|
-
const path = getPassPath(newConfig, oldEnv);
|
|
21
|
-
try {
|
|
22
|
-
const yamlstring = await readPass(path);
|
|
23
|
-
const secrets = load(yamlstring);
|
|
24
|
-
|
|
25
|
-
Object.keys(newConfig.components).forEach(async (componentName) => {
|
|
26
|
-
const environment = await getEnvironment(
|
|
27
|
-
newConfig,
|
|
28
|
-
componentName,
|
|
29
|
-
newEnv
|
|
30
|
-
);
|
|
31
|
-
await upsertAllVariables(
|
|
32
|
-
vorpal,
|
|
33
|
-
pick(
|
|
34
|
-
secrets,
|
|
35
|
-
environment.secretEnvVarKeys
|
|
36
|
-
.filter((k) => !k.hidden)
|
|
37
|
-
.map((k) => k.key)
|
|
38
|
-
),
|
|
39
|
-
newEnv,
|
|
40
|
-
componentName
|
|
41
|
-
);
|
|
42
|
-
});
|
|
43
|
-
await trashItem(path);
|
|
44
|
-
} catch (e) {
|
|
45
|
-
console.warn(`could not migrate secrets for env '${oldEnv}': ${e}`);
|
|
46
|
-
}
|
|
47
|
-
};
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import type { BuildConfig } from "@catladder/pipeline";
|
|
2
|
-
|
|
3
|
-
export type OldGitlabCiFile = {
|
|
4
|
-
variables: {
|
|
5
|
-
CUSTOMER_NAME: string;
|
|
6
|
-
APP_NAME: string;
|
|
7
|
-
COMPONENT_NAME?: string;
|
|
8
|
-
APP_DIR?: string;
|
|
9
|
-
CLUSTER_NAME?: string;
|
|
10
|
-
STAGING_ENABLED?: string;
|
|
11
|
-
};
|
|
12
|
-
include: {
|
|
13
|
-
project: string;
|
|
14
|
-
ref: string;
|
|
15
|
-
file: string;
|
|
16
|
-
}[];
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export const isOldInclude = (gitlabCi: OldGitlabCiFile) => {
|
|
20
|
-
return gitlabCi.include[0]?.project === "catladder/gitlab-ci";
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export const detectBuildConfig = (
|
|
24
|
-
gitlabCi: OldGitlabCiFile
|
|
25
|
-
): BuildConfig["type"] | "monorepo" => {
|
|
26
|
-
if (!isOldInclude(gitlabCi)) {
|
|
27
|
-
throw new Error("unsupported gitlab-ci file");
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const firstInclude = gitlabCi.include[0];
|
|
31
|
-
|
|
32
|
-
if (firstInclude.file === "monorepo.yml") return "monorepo";
|
|
33
|
-
|
|
34
|
-
if (firstInclude.file === "node-kubernetes.yml") {
|
|
35
|
-
return "node";
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (firstInclude.file === "static-js-kubernetes.yml") {
|
|
39
|
-
return "node-static";
|
|
40
|
-
}
|
|
41
|
-
if (firstInclude.file === "meteor-kubernetes.yml") {
|
|
42
|
-
return "meteor";
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (firstInclude.file === "rails-kubernetes.yml") {
|
|
46
|
-
return "rails";
|
|
47
|
-
}
|
|
48
|
-
};
|
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
import { exec, spawn } from "child-process-promise";
|
|
2
|
-
import commandExists from "command-exists-promise";
|
|
3
|
-
import dayjs from "dayjs";
|
|
4
|
-
import { getPreference, hasPreference, setPreference } from "../preferences";
|
|
5
|
-
|
|
6
|
-
const DEBUG = false;
|
|
7
|
-
|
|
8
|
-
const unlockBitwarden = async () => {
|
|
9
|
-
console.error("");
|
|
10
|
-
console.error("# Bitwarden is locked, please unlock:");
|
|
11
|
-
console.error("");
|
|
12
|
-
const promise = spawn("bw", ["unlock", "--raw"], {
|
|
13
|
-
stdio: ["inherit", "pipe", "inherit"],
|
|
14
|
-
});
|
|
15
|
-
let session = null;
|
|
16
|
-
promise.childProcess.stdout.on(
|
|
17
|
-
"data",
|
|
18
|
-
(d) => (session = d.toString("utf-8"))
|
|
19
|
-
);
|
|
20
|
-
await promise;
|
|
21
|
-
await setPreference("bwsession", session);
|
|
22
|
-
};
|
|
23
|
-
const loginBitwarden = async () => {
|
|
24
|
-
console.error("");
|
|
25
|
-
console.error("# Please login to Bitwarden:");
|
|
26
|
-
console.error("");
|
|
27
|
-
const promise = spawn("bw", ["login", "--raw"], {
|
|
28
|
-
stdio: ["inherit", "pipe", "inherit"],
|
|
29
|
-
});
|
|
30
|
-
let session = null;
|
|
31
|
-
promise.childProcess.stdout.on(
|
|
32
|
-
"data",
|
|
33
|
-
(d) => (session = d.toString("utf-8"))
|
|
34
|
-
);
|
|
35
|
-
await promise;
|
|
36
|
-
await setPreference("bwsession", session);
|
|
37
|
-
await syncBitwarden(true); // needs syncing to work properly afterwards
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
const execBitwardenCommand = async (command: string): Promise<any> => {
|
|
41
|
-
if (!(await hasPreference("bwsession"))) {
|
|
42
|
-
await loginBitwarden();
|
|
43
|
-
}
|
|
44
|
-
const session = await getPreference("bwsession");
|
|
45
|
-
const fullCommand = `BW_SESSION='${session}' bw ${command} --raw --nointeraction`;
|
|
46
|
-
if (DEBUG) {
|
|
47
|
-
console.log(fullCommand);
|
|
48
|
-
console.time(fullCommand);
|
|
49
|
-
}
|
|
50
|
-
try {
|
|
51
|
-
const { stdout } = await exec(fullCommand);
|
|
52
|
-
if (DEBUG) {
|
|
53
|
-
console.timeEnd(fullCommand);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (!stdout) {
|
|
57
|
-
return null;
|
|
58
|
-
}
|
|
59
|
-
try {
|
|
60
|
-
return JSON.parse(stdout);
|
|
61
|
-
} catch (e) {
|
|
62
|
-
// no json
|
|
63
|
-
return stdout;
|
|
64
|
-
}
|
|
65
|
-
} catch (e) {
|
|
66
|
-
const isLocked = e.toString().includes("Vault is locked");
|
|
67
|
-
const notLoggedIn = e.toString().includes("You are not logged in");
|
|
68
|
-
if (isLocked) {
|
|
69
|
-
await unlockBitwarden();
|
|
70
|
-
return execBitwardenCommand(command);
|
|
71
|
-
} else if (notLoggedIn) {
|
|
72
|
-
await loginBitwarden();
|
|
73
|
-
return execBitwardenCommand(command);
|
|
74
|
-
} else {
|
|
75
|
-
throw e;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
export const getCollection = async (collectionName: string) => {
|
|
81
|
-
return execBitwardenCommand(`get collection ${collectionName}`);
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
export const getOrganization = async (organizationName: string) => {
|
|
85
|
-
return execBitwardenCommand(`get organization ${organizationName}`);
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
let catladderCollectionId: string;
|
|
89
|
-
|
|
90
|
-
const getCatladderCollectionId = async () => {
|
|
91
|
-
if (!catladderCollectionId) {
|
|
92
|
-
catladderCollectionId = (await getCollection("catladder")).id;
|
|
93
|
-
}
|
|
94
|
-
return catladderCollectionId;
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
let panterOrganizationId: string;
|
|
98
|
-
const getPanterOrganizationId = async () => {
|
|
99
|
-
if (!panterOrganizationId) {
|
|
100
|
-
panterOrganizationId = (await getOrganization("Panter AG")).id;
|
|
101
|
-
}
|
|
102
|
-
return panterOrganizationId;
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
const encode = (data: any) =>
|
|
106
|
-
Buffer.from(JSON.stringify(data)).toString("base64");
|
|
107
|
-
|
|
108
|
-
export const hasBitwarden = () => commandExists("bw");
|
|
109
|
-
|
|
110
|
-
const getItem = async (path: string) => {
|
|
111
|
-
return execBitwardenCommand(`get item ${path}`);
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
export const readPass = async (path: string) => {
|
|
115
|
-
const result = await getItem(path);
|
|
116
|
-
|
|
117
|
-
return result.notes || result.login?.password;
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
const MAX_SYNC_AGE_IN_MINUTES = 30;
|
|
121
|
-
export const syncBitwarden = async (force = true) => {
|
|
122
|
-
const lastSync = (await hasPreference("bwLastSync"))
|
|
123
|
-
? await getPreference("bwLastSync")
|
|
124
|
-
: null;
|
|
125
|
-
if (
|
|
126
|
-
force ||
|
|
127
|
-
!lastSync ||
|
|
128
|
-
dayjs().diff(lastSync, "minutes") >= MAX_SYNC_AGE_IN_MINUTES
|
|
129
|
-
) {
|
|
130
|
-
await execBitwardenCommand("sync");
|
|
131
|
-
await setPreference("bwLastSync", new Date().toISOString());
|
|
132
|
-
} else {
|
|
133
|
-
// skip
|
|
134
|
-
}
|
|
135
|
-
};
|
|
136
|
-
export const insertPass = async (path: string, content: string) => {
|
|
137
|
-
const value = {
|
|
138
|
-
type: 2,
|
|
139
|
-
secureNote: { type: 0 },
|
|
140
|
-
name: path,
|
|
141
|
-
|
|
142
|
-
notes: content,
|
|
143
|
-
collectionIds: [await getCatladderCollectionId()],
|
|
144
|
-
};
|
|
145
|
-
const result = await execBitwardenCommand(`create item ${encode(value)}`);
|
|
146
|
-
await share(result.id);
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
const share = async (itemId: string) =>
|
|
150
|
-
execBitwardenCommand(
|
|
151
|
-
`share ${itemId} ${await getPanterOrganizationId()} ${encode([
|
|
152
|
-
await getCatladderCollectionId(),
|
|
153
|
-
])}`
|
|
154
|
-
);
|
|
155
|
-
|
|
156
|
-
export const trashItem = async (path: string) => {
|
|
157
|
-
const item = await getItem(path);
|
|
158
|
-
|
|
159
|
-
const result = await execBitwardenCommand(`delete item ${item.id}`);
|
|
160
|
-
|
|
161
|
-
return result;
|
|
162
|
-
};
|