🚑 Restore files from nextcloud (#423)

* 🚑Modify nextcloud migration to be able to back up files from next cloud

Co-authored-by: Monta <monta@HP-ProBook-445-14-inch-G9-Notebook-PC-505aadfc.localdomain>
This commit is contained in:
Anton Shepilov
2024-03-07 18:33:08 +01:00
committed by GitHub
parent eacdb29bb2
commit c9ce1fce43
5 changed files with 165 additions and 11 deletions
@@ -402,8 +402,48 @@ export class FileServiceImpl {
}
return data;
}
}
async checkFileExistsS3(id: string): Promise<any> {
try {
const doc = await this.documentRepository.findOne({
id,
company_id: "00000000-0000-4000-0000-000000000000",
});
const externalId = doc.last_version_cache.file_metadata.external_id;
const file = await this.getFile({
id: externalId,
company_id: "00000000-0000-4000-0000-000000000000",
});
const exist = await gr.platformServices.storage.exists(getFilePath(file));
if (exist) {
return { exist: true, file };
} else {
return { exist: false, file };
}
} catch (error) {
logger.error(`Error while checking file ${id} in S3`, error);
return { exist: false, file: null };
}
}
async restoreFileS3(id: string, file: Multipart, options: UploadOptions): Promise<any> {
try {
const result = await this.checkFileExistsS3(id);
if (result.exist) {
return { success: true };
}
await gr.platformServices.storage.write(getFilePath(result.file), file.file, {
chunkNumber: options.chunkNumber,
encryptionAlgo: this.algorithm,
encryptionKey: result.file.encryption_key,
});
return { success: true };
} catch (error) {
logger.error(`Error while uploading missing file ${id} to S3`, error);
return { success: false };
}
}
}
function getFilePath(entity: File): string {
return `${gr.platformServices.storage.getHomeDir()}/files/${entity.company_id}/${
entity.user_id || "anonymous"
@@ -105,6 +105,37 @@ export class FileController {
return { status: deleteResult.deleted ? "success" : "error" };
}
async checkFileS3Exists(
request: FastifyRequest<{ Params: { company_id: string; id: string } }>,
): Promise<{ isInS3: boolean }> {
const params = request.params;
return await gr.services.files.checkFileExistsS3(params.id);
}
async restoreFileS3(
request: FastifyRequest<{
Params: { company_id: string; id: string };
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Querystring: any;
}>,
): Promise<{ resource: PublicFile }> {
const params = request.params;
let file: null | Multipart = null;
if (request.isMultipart()) {
file = await request.file();
}
const q = request.query;
const options: any = {
totalChunks: parseInt(q.resumableTotalChunks || q.total_chunks) || 1,
chunkNumber: parseInt(q.resumableChunkNumber || q.chunk_number) || 1,
};
const result = await gr.services.files.restoreFileS3(params.id, file, options);
return result;
}
}
function getCompanyExecutionContext(
@@ -53,6 +53,20 @@ const routes: FastifyPluginCallback = (fastify: FastifyInstance, options, next)
handler: fileController.checkConsistency.bind(fileController),
});
fastify.route({
method: "GET",
url: "/S3/exist/:id",
preValidation: [fastify.authenticate],
handler: fileController.checkFileS3Exists.bind(fileController),
});
fastify.route({
method: "POST",
url: "/S3/restore/:id",
preValidation: [fastify.authenticate],
handler: fileController.restoreFileS3.bind(fileController),
});
next();
};