@sentclose/sentc-nodejs
Version:
End-to-end encryption sdk
117 lines (116 loc) • 5.41 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Uploader = void 0;
const Sentc_1 = require("../Sentc");
const sentc_node_js_1 = require("@sentclose/sentc_node_js");
const promises_1 = require("node:fs/promises");
const node_path_1 = require("node:path");
/**
* @author Jörn Heinemann <joernheinemann@gmx.de>
* @since 2022/08/27
*/
class Uploader {
constructor(base_url, app_token, user, group_id, other_user_id, upload_callback, group_as_member, chunk_size = 1024 * 1024 * 4) {
this.base_url = base_url;
this.app_token = app_token;
this.user = user;
this.group_id = group_id;
this.other_user_id = other_user_id;
this.upload_callback = upload_callback;
this.group_as_member = group_as_member;
this.chunk_size = chunk_size;
if (group_id && group_id !== "") {
this.belongs_to_id = group_id;
this.belongs_to = "\"Group\""; //the double "" are important for rust serde JSON
}
else if (other_user_id && other_user_id !== "") {
this.belongs_to_id = other_user_id;
this.belongs_to = "\"User\"";
}
else {
this.belongs_to = "\"None\"";
}
}
prepareFileRegister(file, content_key, encrypted_content_key, master_key_id) {
const out = (0, sentc_node_js_1.filePrepareRegisterFile)(master_key_id, content_key, encrypted_content_key, this.belongs_to_id, this.belongs_to, file.name);
const encrypted_file_name = out.encryptedFileName;
const server_input = out.serverInput;
return [server_input, encrypted_file_name];
}
doneFileRegister(server_output) {
const out = (0, sentc_node_js_1.fileDoneRegisterFile)(server_output);
const file_id = out.fileId;
const session_id = out.sessionId;
return [file_id, session_id];
}
async checkFileUpload(fileHandle, fileSize, content_key, session_id, sign = false) {
var _a, _b;
const jwt = await this.user.getJwt();
let sign_key;
if (sign) {
sign_key = await this.user.getSignKey();
}
const totalChunks = Math.ceil(fileSize / this.chunk_size);
let offset = 0;
let currentChunk = 0;
//reset it just in case it was true
Uploader.cancel_upload = false;
const url_prefix = (_b = (_a = Sentc_1.Sentc.options) === null || _a === void 0 ? void 0 : _a.file_part_url) !== null && _b !== void 0 ? _b : undefined;
//each file is encrypted by a new key, and this key is encrypted by the pre-key
let next_file_key = content_key;
while (offset < fileSize) {
const remaining = fileSize - offset;
const readSize = Math.min(this.chunk_size, remaining);
const buffer = Buffer.alloc(readSize);
// eslint-disable-next-line no-await-in-loop
const { bytesRead } = await fileHandle.read(buffer, 0, readSize, offset);
if (bytesRead === 0) {
break;
}
const isEnd = offset + bytesRead >= fileSize;
++currentChunk;
if (currentChunk === 1) {
//first chunk
// eslint-disable-next-line no-await-in-loop
next_file_key = await (0, sentc_node_js_1.fileUploadPartStart)(this.base_url, url_prefix, this.app_token, jwt, session_id, isEnd, currentChunk, content_key, sign_key, buffer);
}
else {
// eslint-disable-next-line no-await-in-loop
next_file_key = await (0, sentc_node_js_1.fileUploadPart)(this.base_url, url_prefix, this.app_token, jwt, session_id, isEnd, currentChunk, next_file_key, sign_key, buffer);
}
if (this.upload_callback) {
this.upload_callback(currentChunk / totalChunks);
}
offset += bytesRead;
if (Uploader.cancel_upload) {
Uploader.cancel_upload = false;
break;
}
}
}
async uploadFileWithPath(path, content_key, encrypted_content_key, master_key_id, sign = false) {
const file_handle = await (0, promises_1.open)(path, "r");
let result;
try {
const file_name = (0, node_path_1.basename)(path);
result = await this.uploadFile(file_handle, file_name, content_key, encrypted_content_key, master_key_id, sign);
}
finally {
await file_handle.close();
}
return result;
}
async uploadFile(file, file_name, content_key, encrypted_content_key, master_key_id, sign = false) {
const jwt = await this.user.getJwt();
const stats = await file.stat();
//create a new file on the server and save the content key id
const out = await (0, sentc_node_js_1.fileRegisterFile)(this.base_url, this.app_token, jwt, master_key_id, content_key, encrypted_content_key, this.belongs_to_id, this.belongs_to, file_name, this.group_id, this.group_as_member);
const session_id = out.sessionId;
const file_id = out.fileId;
const encrypted_file_name = out.encryptedFileName;
await this.checkFileUpload(file, stats.size, content_key, session_id, sign);
return [file_id, encrypted_file_name];
}
}
exports.Uploader = Uploader;
Uploader.cancel_upload = false;