From aa8b9817fbd33ef21f5d7fc63eb5c2710b0eb565 Mon Sep 17 00:00:00 2001 From: APSN4 Date: Sun, 7 Jul 2024 11:52:37 +0300 Subject: [PATCH] feature: encrypt code snippets with a password --- .gitignore | 5 +- .../controller/GetController.java | 9 ++- .../controller/PostController.java | 14 ++++ .../sharing/sharingcodes/dto/PasswordDTO.java | 35 ++++++++++ .../sharing/sharingcodes/model/Code.java | 12 ++++ .../sharingcodes/service/CodeService.java | 3 + .../sharingcodes/service/CodeServiceImpl.java | 15 +++-- src/main/resources/static/js/myScript.js | 33 ++++++++- src/main/resources/templates/getcode.ftlh | 1 + src/main/resources/templates/index.ftlh | 11 +++ src/main/resources/templates/password.ftlh | 67 +++++++++++++++++++ src/main/resources/templates/recent.ftlh | 6 +- 12 files changed, 201 insertions(+), 10 deletions(-) create mode 100644 src/main/java/codes/sharing/sharingcodes/dto/PasswordDTO.java create mode 100644 src/main/resources/templates/password.ftlh diff --git a/.gitignore b/.gitignore index 8544482..4bf547a 100644 --- a/.gitignore +++ b/.gitignore @@ -37,4 +37,7 @@ out/ .vscode/ ### H2 Database ### -*.db \ No newline at end of file +*.db + +### macOS files ### +.DS_Store \ No newline at end of file diff --git a/src/main/java/codes/sharing/sharingcodes/controller/GetController.java b/src/main/java/codes/sharing/sharingcodes/controller/GetController.java index 700b2d7..cc1b610 100644 --- a/src/main/java/codes/sharing/sharingcodes/controller/GetController.java +++ b/src/main/java/codes/sharing/sharingcodes/controller/GetController.java @@ -20,9 +20,16 @@ public GetController(@Autowired CodeService codeService) { } @GetMapping("/code/{N}") - public String getNthCode(@PathVariable String N, Model model) { + public String getNthCode(@PathVariable String N, @RequestParam(value = "password", required = false) String password, Model model) { try { Code currentCode = codeService.getById(N); + + if (password == null) password = ""; + if (!password.equals(currentCode.getPassword())) { + return "password"; + } + codeService.refreshCode(currentCode); + DateDTO dateDTO = codeService.formatDate(currentCode.getDate()); model.addAttribute("pieceOfCode", currentCode); model.addAttribute("dateDTO", dateDTO); diff --git a/src/main/java/codes/sharing/sharingcodes/controller/PostController.java b/src/main/java/codes/sharing/sharingcodes/controller/PostController.java index f8586db..ca9b0a2 100644 --- a/src/main/java/codes/sharing/sharingcodes/controller/PostController.java +++ b/src/main/java/codes/sharing/sharingcodes/controller/PostController.java @@ -1,12 +1,15 @@ package codes.sharing.sharingcodes.controller; +import codes.sharing.sharingcodes.dto.PasswordDTO; import codes.sharing.sharingcodes.model.Code; import codes.sharing.sharingcodes.service.CodeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.stereotype.Controller; +import java.util.HashMap; import java.util.Map; @Controller @@ -40,4 +43,15 @@ public Map createApiCode(@RequestBody Code newCode) { public Object getLatestApiCodes() { return codeService.getLatestNCode(10); } + + @PostMapping(value = "/api/code/password", produces = MediaType.APPLICATION_JSON_VALUE) + @ResponseBody + public ResponseEntity checkPassword(@RequestBody PasswordDTO passwordDTO) { + Code currentCode = codeService.getById(passwordDTO.getId()); + if (currentCode.getPassword().equals(passwordDTO.getPassword())) { + return ResponseEntity.ok().build(); + } else { + return ResponseEntity.badRequest().build(); + } + } } \ No newline at end of file diff --git a/src/main/java/codes/sharing/sharingcodes/dto/PasswordDTO.java b/src/main/java/codes/sharing/sharingcodes/dto/PasswordDTO.java new file mode 100644 index 0000000..0593346 --- /dev/null +++ b/src/main/java/codes/sharing/sharingcodes/dto/PasswordDTO.java @@ -0,0 +1,35 @@ +package codes.sharing.sharingcodes.dto; + +public class PasswordDTO { + + public PasswordDTO(String password, String id) { + this.password = password; + this.id = id; + } + + public PasswordDTO(String password) { + this.password = password; + } + public PasswordDTO() { + this.password = ""; + } + + private String password; + private String id; + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } +} diff --git a/src/main/java/codes/sharing/sharingcodes/model/Code.java b/src/main/java/codes/sharing/sharingcodes/model/Code.java index 080340b..167465f 100644 --- a/src/main/java/codes/sharing/sharingcodes/model/Code.java +++ b/src/main/java/codes/sharing/sharingcodes/model/Code.java @@ -36,6 +36,9 @@ public class Code { @Column(name = "timelimit") private boolean timeLimit; + @Column(name = "password") + private String password; + public Code() { } @@ -53,6 +56,7 @@ public Code(Code code) { if (this.time > 0) { this.timeLimit = true; } + this.password = code.getPassword() == null ? "" : code.getPassword(); } public String getId() { @@ -131,4 +135,12 @@ public String shortCode() { return getCode(); } } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } } \ No newline at end of file diff --git a/src/main/java/codes/sharing/sharingcodes/service/CodeService.java b/src/main/java/codes/sharing/sharingcodes/service/CodeService.java index 9c1ebbc..3d8290a 100644 --- a/src/main/java/codes/sharing/sharingcodes/service/CodeService.java +++ b/src/main/java/codes/sharing/sharingcodes/service/CodeService.java @@ -1,6 +1,7 @@ package codes.sharing.sharingcodes.service; import codes.sharing.sharingcodes.dto.DateDTO; +import codes.sharing.sharingcodes.dto.PasswordDTO; import codes.sharing.sharingcodes.model.Code; import java.util.List; @@ -11,6 +12,8 @@ public interface CodeService { public void putCode(Code newCode); + public void refreshCode(Code code); + public List getLatestNCode(int n); public boolean isExist(String id); diff --git a/src/main/java/codes/sharing/sharingcodes/service/CodeServiceImpl.java b/src/main/java/codes/sharing/sharingcodes/service/CodeServiceImpl.java index d0c266a..cf2222c 100644 --- a/src/main/java/codes/sharing/sharingcodes/service/CodeServiceImpl.java +++ b/src/main/java/codes/sharing/sharingcodes/service/CodeServiceImpl.java @@ -1,6 +1,7 @@ package codes.sharing.sharingcodes.service; import codes.sharing.sharingcodes.dto.DateDTO; +import codes.sharing.sharingcodes.dto.PasswordDTO; import codes.sharing.sharingcodes.exceptions.NotFoundSnippet; import codes.sharing.sharingcodes.model.Code; import codes.sharing.sharingcodes.repository.CodeRepository; @@ -24,10 +25,6 @@ public CodeServiceImpl(@Autowired CodeRepository repo) { @Override public Code getById(String id) { - Code code = repo.findById(id).orElseThrow(() -> new NotFoundSnippet(id)); - if (code.hasLimit()) { - refresh(code); - } return repo.findById(id).orElseThrow(() -> new NotFoundSnippet(id)); } @@ -38,6 +35,14 @@ public void putCode(Code newCode) { repo.save(code); } + @Override + public void refreshCode(Code code) { + if (code.hasLimit()) { + refresh(code); + } + } + + @Override public List getLatestNCode(int n) { List codes = (List) repo.findAll(); @@ -78,7 +83,7 @@ public List superGetAll() { private void refresh(Code code) { if (code.isViewsLimit() && code.getViews() >= 0) { code.setViews(code.getViews() - 1); - if (code.getViews() < 0) { + if (code.getViews() <= 0) { repo.delete(code); return; } diff --git a/src/main/resources/static/js/myScript.js b/src/main/resources/static/js/myScript.js index c179554..d0deaf1 100644 --- a/src/main/resources/static/js/myScript.js +++ b/src/main/resources/static/js/myScript.js @@ -22,7 +22,8 @@ function send() { let object = { "code": document.getElementById("code_snippet").value, "views": document.getElementById("views_restriction").value, - "time": document.getElementById("time_restriction").value + "time": document.getElementById("time_restriction").value, + "password": document.getElementById("password_field").value }; let json = JSON.stringify(object); @@ -55,4 +56,32 @@ function send() { errorCode.innerHTML = xhr.status + " " + xhr.statusText; return; } -} \ No newline at end of file +} + +function check() { + const codeId = location.pathname.substring(6); + var object = { + "password": document.getElementById("password_field").value, + "id": codeId + }; + let json = JSON.stringify(object); + + try { + xhr = new XMLHttpRequest(); + xhr.open("POST", '/api/code/password', false) + xhr.setRequestHeader('Content-type', 'application/json; charset=utf-8'); + xhr.send(json); + + var url = location.protocol + '//' + location.host + location.pathname + '?password=' + object.password; + + if (xhr.status == 200) { + window.location.href = url; + } else if (xhr.status == 400){ + dangerMessage.style.display = "block"; + } else { + window.location.href = url; + } + } catch (error) { + console.error(error.message); + } +} diff --git a/src/main/resources/templates/getcode.ftlh b/src/main/resources/templates/getcode.ftlh index fa7fde5..128a0f4 100644 --- a/src/main/resources/templates/getcode.ftlh +++ b/src/main/resources/templates/getcode.ftlh @@ -5,6 +5,7 @@ + diff --git a/src/main/resources/templates/index.ftlh b/src/main/resources/templates/index.ftlh index bc2eebe..ebfe6cc 100644 --- a/src/main/resources/templates/index.ftlh +++ b/src/main/resources/templates/index.ftlh @@ -60,7 +60,18 @@ This will allow viewing a code snippet for a certain period of time, and after its expiration, the code snippet is deleted from the database. +

+ +

+
+
+
+ Password +
+ +
+
diff --git a/src/main/resources/templates/password.ftlh b/src/main/resources/templates/password.ftlh new file mode 100644 index 0000000..f52c416 --- /dev/null +++ b/src/main/resources/templates/password.ftlh @@ -0,0 +1,67 @@ + + + + + + + + + + + + + Secret code snippet! + + + + + + +
+
+
+ +
+
+
+ +
+ + +
+ This code snippet has been encrypted. You must enter your password to view this code. + +
+
+
+
+
+
+ + + + + + + \ No newline at end of file diff --git a/src/main/resources/templates/recent.ftlh b/src/main/resources/templates/recent.ftlh index e2fa1da..ff5560f 100644 --- a/src/main/resources/templates/recent.ftlh +++ b/src/main/resources/templates/recent.ftlh @@ -42,7 +42,11 @@
${pieceOfCode.getId()}
${pieceOfCode.date} -

${pieceOfCode.shortCode()}

+ <#if !pieceOfCode.getPassword()?has_content> +

${pieceOfCode.shortCode()}

+ <#else> +

This is an encrypted code snippet.

+