Added unique ID generator
- Updated data cleaning feature - Added fileID database logic
This commit is contained in:
parent
e179cdf2dc
commit
6a1e91f5d8
@ -34,6 +34,7 @@ export class DownloadComponent {
|
|||||||
fileDownloadFinished: boolean = false;
|
fileDownloadFinished: boolean = false;
|
||||||
waitingForPassword: boolean = false;
|
waitingForPassword: boolean = false;
|
||||||
downloadProgress: number = 0;
|
downloadProgress: number = 0;
|
||||||
|
targetUploadProgress: number = 0;
|
||||||
downloadDuration: string = "";
|
downloadDuration: string = "";
|
||||||
passwordWrong: boolean = false;
|
passwordWrong: boolean = false;
|
||||||
|
|
||||||
@ -155,8 +156,8 @@ export class DownloadComponent {
|
|||||||
// Calculate the percentage of download completed
|
// Calculate the percentage of download completed
|
||||||
if(progressEvent.total) {
|
if(progressEvent.total) {
|
||||||
const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
|
const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
|
||||||
this.downloadProgress = percentCompleted;
|
this.targetUploadProgress = percentCompleted;
|
||||||
console.log(percentCompleted + '%'); // Log the percentage or update any progress UI component
|
this.smoothProgressUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -201,6 +202,16 @@ export class DownloadComponent {
|
|||||||
private wrongPassword() {
|
private wrongPassword() {
|
||||||
this.passwordWrong = true;
|
this.passwordWrong = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
smoothProgressUpdate() {
|
||||||
|
if (this.downloadProgress < this.targetUploadProgress) {
|
||||||
|
this.downloadProgress += 0.01 * (this.targetUploadProgress - this.downloadProgress);
|
||||||
|
requestAnimationFrame(this.smoothProgressUpdate.bind(this));
|
||||||
|
} else if (this.downloadProgress > this.targetUploadProgress) {
|
||||||
|
// Handle overshoot
|
||||||
|
this.downloadProgress = this.targetUploadProgress;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
interface DownloadInfo {
|
interface DownloadInfo {
|
||||||
downloadable: boolean;
|
downloadable: boolean;
|
||||||
|
@ -61,7 +61,12 @@ public class RethinkDBService {
|
|||||||
r.db(config.getDatabase()).tableCreate("id_store").run(connection).stream();
|
r.db(config.getDatabase()).tableCreate("id_store").run(connection).stream();
|
||||||
log.debug("Table 'id_store' created successfully.");
|
log.debug("Table 'id_store' created successfully.");
|
||||||
} catch (ReqlOpFailedError e) {
|
} catch (ReqlOpFailedError e) {
|
||||||
log.debug("Table 'id_store' already exists. No action needed.");
|
log.debug("Table 'id_store' already exists.");
|
||||||
|
if(autoResetOnStartup) {
|
||||||
|
log.debug("Clearing content...");
|
||||||
|
r.db(config.getDatabase()).table("id_store").delete().run(connection);
|
||||||
|
log.debug("Table 'id_store' cleared successfully.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// rethinkdb check if table expired_file_uploads exists
|
// rethinkdb check if table expired_file_uploads exists
|
||||||
@ -69,7 +74,12 @@ public class RethinkDBService {
|
|||||||
r.db(config.getDatabase()).tableCreate("expired_file_uploads").run(connection).stream();
|
r.db(config.getDatabase()).tableCreate("expired_file_uploads").run(connection).stream();
|
||||||
log.debug("Table 'expired_file_uploads' created successfully.");
|
log.debug("Table 'expired_file_uploads' created successfully.");
|
||||||
} catch (ReqlOpFailedError e) {
|
} catch (ReqlOpFailedError e) {
|
||||||
log.debug("Table 'expired_file_uploads' already exists. No action needed.");
|
log.debug("Table 'expired_file_uploads' already exists.");
|
||||||
|
if(autoResetOnStartup) {
|
||||||
|
log.debug("Clearing content...");
|
||||||
|
r.db(config.getDatabase()).table("expired_file_uploads").delete().run(connection);
|
||||||
|
log.debug("Table 'expired_file_uploads' cleared successfully.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
log.info("Database ready for operation!");
|
log.info("Database ready for operation!");
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
package de.w665.sharepulse.db.repo;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.rethinkdb.RethinkDB;
|
||||||
|
import com.rethinkdb.net.Connection;
|
||||||
|
import com.rethinkdb.net.Result;
|
||||||
|
import de.w665.sharepulse.db.RethinkDBConnector;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public class FileIdRepository {
|
||||||
|
|
||||||
|
private final RethinkDB r;
|
||||||
|
private final Connection connection;
|
||||||
|
private final Gson gson;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public FileIdRepository(RethinkDBConnector connector) {
|
||||||
|
this.r = connector.getR();
|
||||||
|
this.connection = connector.getConnection();
|
||||||
|
this.gson = new GsonBuilder().create();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void insertFileId(String fileId) {
|
||||||
|
r.db("sharepulse").table("id_store").insert(r.hashMap("fileId", fileId)).run(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean fileIdExists(String fileId) {
|
||||||
|
Result<Object> result = r.db("sharepulse").table("id_store")
|
||||||
|
.filter(r.hashMap("fileId", fileId))
|
||||||
|
.run(connection);
|
||||||
|
|
||||||
|
return result.hasNext();
|
||||||
|
}
|
||||||
|
}
|
@ -82,7 +82,7 @@ public class Download extends ApiRestController {
|
|||||||
Optional<FileUpload> optionalFileUpload = fileService.getFileUploadByFileId(fileId);
|
Optional<FileUpload> optionalFileUpload = fileService.getFileUploadByFileId(fileId);
|
||||||
FileUpload fileUpload = optionalFileUpload.orElse(null);
|
FileUpload fileUpload = optionalFileUpload.orElse(null);
|
||||||
if(optionalFileUpload.isEmpty()) {
|
if(optionalFileUpload.isEmpty()) {
|
||||||
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
|
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean downloadable = !fileUpload.isSingleDownload() || fileUpload.getDownloadCount() == 0;
|
boolean downloadable = !fileUpload.isSingleDownload() || fileUpload.getDownloadCount() == 0;
|
||||||
|
@ -1,34 +1,51 @@
|
|||||||
package de.w665.sharepulse.service;
|
package de.w665.sharepulse.service;
|
||||||
|
|
||||||
|
import de.w665.sharepulse.db.repo.FileIdRepository;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.security.SecureRandom;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class FileIdService {
|
public class FileIdService {
|
||||||
|
|
||||||
private static int dailyCounter = 0;
|
@Value("${sharepulse.fileid.length}")
|
||||||
private static String lastDate = "";
|
private int fileIdLength;
|
||||||
|
|
||||||
// Not safe to use
|
@Value("${sharepulse.fileid.charset}")
|
||||||
public static synchronized String generateId() {
|
private String CHARSET;
|
||||||
String today = new SimpleDateFormat("yyMMdd").format(new Date());
|
|
||||||
|
|
||||||
if (!today.equals(lastDate)) {
|
private final FileIdRepository fileIdRepository;
|
||||||
dailyCounter = 0;
|
private static final SecureRandom RANDOM = new SecureRandom();
|
||||||
lastDate = today;
|
|
||||||
|
@Autowired
|
||||||
|
public FileIdService(FileIdRepository fileIdRepository) {
|
||||||
|
this.fileIdRepository = fileIdRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String generateId() {
|
||||||
|
String uniqueId;
|
||||||
|
do {
|
||||||
|
uniqueId = generateRandomCode(fileIdLength);
|
||||||
|
} while (fileIdRepository.fileIdExists(uniqueId));
|
||||||
|
fileIdRepository.insertFileId(uniqueId);
|
||||||
|
return uniqueId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String generateRandomCode(int length) {
|
||||||
|
StringBuilder sb = new StringBuilder(length);
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
int index = RANDOM.nextInt(CHARSET.length());
|
||||||
|
sb.append(CHARSET.charAt(index));
|
||||||
}
|
}
|
||||||
|
return sb.toString();
|
||||||
String counterEncoded = Integer.toString(++dailyCounter, 36).toUpperCase();
|
|
||||||
|
|
||||||
return today + counterEncoded;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String generateNewUniqueId() {
|
public String generateNewUniqueId() {
|
||||||
return generateId();
|
return generateId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,17 +5,19 @@ import de.w665.sharepulse.model.FileUpload;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.security.SecureRandom;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
public class FileSecurityService {
|
public class FileSecurityService {
|
||||||
|
|
||||||
@Value("${sharepulse.filepassword-length}")
|
@Value("${sharepulse.filepassword.length}")
|
||||||
private int passwordLength;
|
private int passwordLength;
|
||||||
@Value("${sharepulse.filepassword-charset}")
|
@Value("${sharepulse.filepassword.charset}")
|
||||||
private String passwordCharset;
|
private String passwordCharset;
|
||||||
private final Random random = new Random();
|
private final Random random = new SecureRandom();
|
||||||
|
|
||||||
public boolean verifyDownloadPermission(FileUpload file, String password) throws NoDownloadPermissionException {
|
public boolean verifyDownloadPermission(FileUpload file, String password) throws NoDownloadPermissionException {
|
||||||
|
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
# Application config
|
# Application config
|
||||||
sharepulse.temp-filestore-path=/temp-filestore
|
sharepulse.temp-filestore-path=/temp-filestore
|
||||||
sharepulse.filepassword-length=6
|
|
||||||
sharepulse.filepassword-charset=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
|
|
||||||
sharepulse.auto-reset-on-startup=true
|
sharepulse.auto-reset-on-startup=true
|
||||||
|
sharepulse.fileid.length=6
|
||||||
|
sharepulse.fileid.charset=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
|
||||||
|
sharepulse.filepassword.length=6
|
||||||
|
sharepulse.filepassword.charset=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
|
||||||
|
|
||||||
# Static path
|
# Static path
|
||||||
spring.web.resources.static-locations=classpath:/static/browser/
|
spring.web.resources.static-locations=classpath:/static/browser/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user