enhance repository creation logic to check for existing repositories and handle errors appropriately

This commit is contained in:
Jakub Trávník 2025-12-04 13:31:08 +01:00
parent abe6eb79d8
commit 1d4263046c

View file

@ -25,14 +25,14 @@ const encryptConfig = async (config: RepositoryConfig): Promise<RepositoryConfig
switch (config.backend) { switch (config.backend) {
case "s3": case "s3":
case "r2": case "r2":
encryptedConfig.accessKeyId = await cryptoUtils.encrypt(config.accessKeyId); encryptedConfig.accessKeyId = await cryptoUtils.encrypt(config.accessKeyId);
encryptedConfig.secretAccessKey = await cryptoUtils.encrypt(config.secretAccessKey); encryptedConfig.secretAccessKey = await cryptoUtils.encrypt(config.secretAccessKey);
break; break;
case "gcs": case "gcs":
encryptedConfig.credentialsJson = await cryptoUtils.encrypt(config.credentialsJson); encryptedConfig.credentialsJson = await cryptoUtils.encrypt(config.credentialsJson);
break; break;
case "azure": case "azure":
encryptedConfig.accountKey = await cryptoUtils.encrypt(config.accountKey); encryptedConfig.accountKey = await cryptoUtils.encrypt(config.accountKey);
break; break;
case "rest": case "rest":
if (config.username) { if (config.username) {
@ -43,7 +43,7 @@ const encryptConfig = async (config: RepositoryConfig): Promise<RepositoryConfig
} }
break; break;
case "sftp": case "sftp":
encryptedConfig.privateKey = await cryptoUtils.encrypt(config.privateKey); encryptedConfig.privateKey = await cryptoUtils.encrypt(config.privateKey);
break; break;
} }
@ -85,6 +85,24 @@ const createRepository = async (name: string, config: RepositoryConfig, compress
const encryptedConfig = await encryptConfig(processedConfig); const encryptedConfig = await encryptConfig(processedConfig);
const repoExists = await restic
.snapshots(encryptedConfig)
.then(() => true)
.catch(() => false);
if (repoExists && !config.isExistingRepository) {
throw new ConflictError(
`A restic repository already exists at this location. ` +
`If you want to use the existing repository, set "isExistingRepository": true in the config.`
);
}
if (!repoExists && config.isExistingRepository) {
throw new InternalServerError(
`Cannot access existing repository. Verify the path/credentials are correct and the repository exists.`
);
}
const [created] = await db const [created] = await db
.insert(repositoriesTable) .insert(repositoriesTable)
.values({ .values({
@ -104,27 +122,9 @@ const createRepository = async (name: string, config: RepositoryConfig, compress
let error: string | null = null; let error: string | null = null;
if (config.isExistingRepository) { if (!repoExists) {
const result = await restic
.snapshots(encryptedConfig)
.then(() => ({ error: null }))
.catch((err) => ({ error: err }));
error = result.error;
} else {
const initResult = await restic.init(encryptedConfig); const initResult = await restic.init(encryptedConfig);
error = initResult.error; error = initResult.error;
if (error) {
const errorStr = typeof error === "string" ? error : (error as Error)?.message || "";
if (errorStr.includes("config file already exists")) {
const verifyResult = await restic
.snapshots(encryptedConfig)
.then(() => ({ error: null }))
.catch((err) => ({ error: err }));
error = verifyResult.error;
}
}
} }
if (!error) { if (!error) {