@lacrous/omnicloud 0.2.6 → 0.2.7
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/cli.js +84 -3
- package/package.json +4 -4
- package/server/index.js +1 -1
package/dist/cli.js
CHANGED
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
// src/cli.ts
|
|
4
4
|
import { spawn } from "child_process";
|
|
5
|
-
import {
|
|
5
|
+
import { randomBytes } from "crypto";
|
|
6
|
+
import { chmodSync, existsSync, readFileSync, realpathSync, writeFileSync } from "fs";
|
|
6
7
|
import { createRequire } from "module";
|
|
7
8
|
import { dirname, join, resolve } from "path";
|
|
9
|
+
import { createInterface } from "readline/promises";
|
|
8
10
|
import { fileURLToPath } from "url";
|
|
9
11
|
var packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
10
12
|
var serverDir = join(packageRoot, "server");
|
|
@@ -182,7 +184,19 @@ ${USAGE}`);
|
|
|
182
184
|
`);
|
|
183
185
|
return 0;
|
|
184
186
|
}
|
|
185
|
-
|
|
187
|
+
const envPath = resolve(args.envFile ?? ".env");
|
|
188
|
+
if (args.command === "start" && !existsSync(envPath) && !env.DATABASE_URL) {
|
|
189
|
+
const outcome = await firstRunSetup(envPath);
|
|
190
|
+
if (outcome === "not-interactive") {
|
|
191
|
+
process.stderr.write(
|
|
192
|
+
`omnicloud: no configuration found. Create ${envPath} (see https://github.com/Lacrous/OmniCloud#configuration) or run omnicloud in a terminal.
|
|
193
|
+
`
|
|
194
|
+
);
|
|
195
|
+
return 1;
|
|
196
|
+
}
|
|
197
|
+
if (outcome !== "saved") return 1;
|
|
198
|
+
}
|
|
199
|
+
loadEnvFile(envPath, env);
|
|
186
200
|
try {
|
|
187
201
|
if (args.command === "migrate") {
|
|
188
202
|
await migrate(env);
|
|
@@ -203,6 +217,71 @@ ${USAGE}`);
|
|
|
203
217
|
${USAGE}`);
|
|
204
218
|
return 2;
|
|
205
219
|
}
|
|
220
|
+
function buildEnvFile(values) {
|
|
221
|
+
return [
|
|
222
|
+
"# Written by `omnicloud` on first run. Keep this file private.",
|
|
223
|
+
`DATABASE_URL=${values.databaseUrl}`,
|
|
224
|
+
`TELEGRAM_API_ID=${values.apiId}`,
|
|
225
|
+
`TELEGRAM_API_HASH=${values.apiHash}`,
|
|
226
|
+
`OMNICLOUD_ENCRYPTION_KEY=${values.encryptionKey}`,
|
|
227
|
+
""
|
|
228
|
+
].join("\n");
|
|
229
|
+
}
|
|
230
|
+
function validateSetup(values) {
|
|
231
|
+
if (!/^postgres(ql)?:\/\/.+@.+\/.+$/.test(values.databaseUrl)) {
|
|
232
|
+
return "DATABASE_URL must look like postgresql://user:password@host:5432/database";
|
|
233
|
+
}
|
|
234
|
+
if (!/^[1-9][0-9]*$/.test(values.apiId)) {
|
|
235
|
+
return "TELEGRAM_API_ID must be the number shown at my.telegram.org";
|
|
236
|
+
}
|
|
237
|
+
if (!/^[0-9a-f]{32}$/i.test(values.apiHash)) {
|
|
238
|
+
return "TELEGRAM_API_HASH must be the 32-character value shown at my.telegram.org";
|
|
239
|
+
}
|
|
240
|
+
return null;
|
|
241
|
+
}
|
|
242
|
+
async function firstRunSetup(envPath) {
|
|
243
|
+
if (!process.stdin.isTTY) return "not-interactive";
|
|
244
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
245
|
+
try {
|
|
246
|
+
process.stdout.write(
|
|
247
|
+
"\nWelcome to OmniCloud. No .env file was found, so let's create one.\n\n1. PostgreSQL database\n Format: postgresql://USER:PASSWORD@HOST:PORT/DATABASE\n The default docker setup uses postgresql://omnicloud:omnicloud@127.0.0.1:5432/omnicloud\n\n2. Telegram API credentials\n Open https://my.telegram.org, log in, choose 'API development tools',\n and create an application. Copy the api_id and api_hash.\n\n"
|
|
248
|
+
);
|
|
249
|
+
const databaseUrl = (await rl.question("DATABASE_URL: ")).trim();
|
|
250
|
+
const apiId = (await rl.question("TELEGRAM_API_ID: ")).trim();
|
|
251
|
+
const apiHash = (await rl.question("TELEGRAM_API_HASH: ")).trim();
|
|
252
|
+
const problem = validateSetup({ databaseUrl, apiId, apiHash });
|
|
253
|
+
if (problem) {
|
|
254
|
+
process.stderr.write(`
|
|
255
|
+
omnicloud: ${problem}
|
|
256
|
+
Run omnicloud again to retry.
|
|
257
|
+
`);
|
|
258
|
+
return "invalid";
|
|
259
|
+
}
|
|
260
|
+
const answer = (await rl.question(`
|
|
261
|
+
Save these settings to ${envPath}? [Y/n] `)).trim().toLowerCase();
|
|
262
|
+
if (answer === "n" || answer === "no") {
|
|
263
|
+
process.stdout.write("Nothing was saved.\n");
|
|
264
|
+
return "declined";
|
|
265
|
+
}
|
|
266
|
+
writeFileSync(
|
|
267
|
+
envPath,
|
|
268
|
+
buildEnvFile({
|
|
269
|
+
databaseUrl,
|
|
270
|
+
apiId,
|
|
271
|
+
apiHash,
|
|
272
|
+
encryptionKey: randomBytes(32).toString("hex")
|
|
273
|
+
}),
|
|
274
|
+
{ mode: 384 }
|
|
275
|
+
);
|
|
276
|
+
chmodSync(envPath, 384);
|
|
277
|
+
process.stdout.write(`Saved ${envPath}. A private encryption key was generated for you.
|
|
278
|
+
|
|
279
|
+
`);
|
|
280
|
+
return "saved";
|
|
281
|
+
} finally {
|
|
282
|
+
rl.close();
|
|
283
|
+
}
|
|
284
|
+
}
|
|
206
285
|
function isEntryPoint() {
|
|
207
286
|
const entry = process.argv[1];
|
|
208
287
|
if (!entry) return false;
|
|
@@ -216,8 +295,10 @@ if (isEntryPoint()) {
|
|
|
216
295
|
main(process.argv.slice(2)).then((code) => process.exit(code));
|
|
217
296
|
}
|
|
218
297
|
export {
|
|
298
|
+
buildEnvFile,
|
|
219
299
|
loadEnvFile,
|
|
220
300
|
main,
|
|
221
301
|
parseArgs,
|
|
222
|
-
parseEnvFile
|
|
302
|
+
parseEnvFile,
|
|
303
|
+
validateSetup
|
|
223
304
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lacrous/omnicloud",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.7",
|
|
4
4
|
"description": "SDK and core building blocks for OmniCloud — self-hosted cloud storage powered by your Telegram account.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -48,9 +48,9 @@
|
|
|
48
48
|
"prisma": "^6.2.0"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@omnicloud/core": "0.2.
|
|
52
|
-
"@omnicloud/shared": "0.2.
|
|
53
|
-
"@omnicloud/telegram": "0.2.
|
|
51
|
+
"@omnicloud/core": "0.2.7",
|
|
52
|
+
"@omnicloud/shared": "0.2.7",
|
|
53
|
+
"@omnicloud/telegram": "0.2.7",
|
|
54
54
|
"@types/node": "^22.10.0",
|
|
55
55
|
"esbuild": "0.25.12",
|
|
56
56
|
"tsup": "^8.3.0",
|
package/server/index.js
CHANGED
|
@@ -4685,7 +4685,7 @@ function encryptionCheck(configured) {
|
|
|
4685
4685
|
}
|
|
4686
4686
|
|
|
4687
4687
|
// ../../apps/api/src/routes/storage.ts
|
|
4688
|
-
var VERSION = "0.2.
|
|
4688
|
+
var VERSION = "0.2.7";
|
|
4689
4689
|
function registerStorageRoutes(app2, container2) {
|
|
4690
4690
|
app2.get("/api/health", async () => {
|
|
4691
4691
|
const database = await probeDatabase(container2);
|