diff --git a/client/src/actions.ts b/client/src/actions.ts
index b30c683..e7ff8a4 100644
--- a/client/src/actions.ts
+++ b/client/src/actions.ts
@@ -1,4 +1,10 @@
-import { addFollower, removeFollower, signup } from "./api/Person";
+import {
+ addFollower,
+ deleteSelf,
+ removeFollower,
+ signup,
+ updateSelf,
+} from "./api/Person";
import { ActionFunctionArgs, redirect } from "react-router-dom";
import { login } from "./api/Token";
import { isError } from "./api/dto";
@@ -66,6 +72,16 @@ export async function profileSelfAction({ request }: ActionFunctionArgs) {
formData.get("text")!.toString(),
parseInt(formData.get("postId")!.toString()),
);
+ } else if (intent == "user") {
+ return await updateSelf(
+ formData.get("username")!.toString(),
+ formData.get("fullName")!.toString(),
+ formData.get("password")!.toString(),
+ );
+ } else if (intent == "deleteSelf") {
+ await deleteSelf();
+ deleteToken();
+ return redirect("/");
}
}
diff --git a/client/src/api/Person.ts b/client/src/api/Person.ts
index 6140f08..9ac5354 100644
--- a/client/src/api/Person.ts
+++ b/client/src/api/Person.ts
@@ -20,6 +20,22 @@ export async function signup(
});
}
+export async function updateSelf(
+ username: string,
+ fullName: string,
+ password: string,
+): Promise
{
+ return fetchJSONAuth("/person/self", "PATCH", PersonToResp, {
+ username,
+ fullName,
+ password,
+ });
+}
+
+export async function deleteSelf(): Promise {
+ return fetchJSONAuth("/person/self", "DELETE", NoContentToResp);
+}
+
export async function getPersonByUuid(uuid: string): Promise {
return fetchJSONAuth("/person/by-uuid/" + uuid, "GET", PersonToResp);
}
diff --git a/server/src/main/java/com/usatiuk/tjv/y/server/controller/PersonController.java b/server/src/main/java/com/usatiuk/tjv/y/server/controller/PersonController.java
index fac971b..6fb0863 100644
--- a/server/src/main/java/com/usatiuk/tjv/y/server/controller/PersonController.java
+++ b/server/src/main/java/com/usatiuk/tjv/y/server/controller/PersonController.java
@@ -3,13 +3,17 @@ package com.usatiuk.tjv.y.server.controller;
import com.usatiuk.tjv.y.server.dto.PersonSignupTo;
import com.usatiuk.tjv.y.server.dto.PersonTo;
import com.usatiuk.tjv.y.server.dto.converters.PersonMapper;
+import com.usatiuk.tjv.y.server.entity.Chat;
import com.usatiuk.tjv.y.server.entity.Person;
+import com.usatiuk.tjv.y.server.service.ChatService;
import com.usatiuk.tjv.y.server.service.PersonService;
import com.usatiuk.tjv.y.server.service.exceptions.UserAlreadyExistsException;
import com.usatiuk.tjv.y.server.service.exceptions.UserNotFoundException;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
+import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
+import org.springframework.web.server.ResponseStatusException;
import java.security.Principal;
import java.util.Optional;
@@ -20,11 +24,15 @@ import java.util.stream.StreamSupport;
@RequestMapping(value = "/person", produces = MediaType.APPLICATION_JSON_VALUE)
public class PersonController {
private final PersonService personService;
+ private final ChatService chatService;
private final PersonMapper personMapper;
+ private final PasswordEncoder passwordEncoder;
- public PersonController(PersonService personService, PersonMapper personMapper) {
+ public PersonController(PersonService personService, ChatService chatService, PersonMapper personMapper, PasswordEncoder passwordEncoder) {
this.personService = personService;
+ this.chatService = chatService;
this.personMapper = personMapper;
+ this.passwordEncoder = passwordEncoder;
}
@PostMapping
@@ -67,6 +75,27 @@ public class PersonController {
return personMapper.makeDto(found.get());
}
+ @PatchMapping(path = "/self")
+ public PersonTo update(Principal principal, @RequestBody PersonSignupTo personSignupTo) {
+ var person = personService.readById(principal.getName()).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
+ person.setUsername(personSignupTo.username())
+ .setFullName(personSignupTo.fullName());
+ if (!personSignupTo.password().isEmpty()) person.setPassword(passwordEncoder.encode(personSignupTo.password()));
+ personService.update(person);
+ return personMapper.makeDto(person);
+ }
+
+ @DeleteMapping(path = "/self")
+ @ResponseStatus(HttpStatus.NO_CONTENT)
+ public void delete(Principal principal) {
+ var person = personService.readById(principal.getName()).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
+ for (Chat c : person.getChats()) {
+ c.getMembers().remove(person);
+ chatService.update(c);
+ }
+ personService.deleteById(principal.getName());
+ }
+
@GetMapping
public Stream getAll() throws UserNotFoundException {
return StreamSupport.stream(personService.readAll().spliterator(), false).map(personMapper::makeDto);
diff --git a/server/src/main/java/com/usatiuk/tjv/y/server/entity/Chat.java b/server/src/main/java/com/usatiuk/tjv/y/server/entity/Chat.java
index d6b91f8..193cf6c 100644
--- a/server/src/main/java/com/usatiuk/tjv/y/server/entity/Chat.java
+++ b/server/src/main/java/com/usatiuk/tjv/y/server/entity/Chat.java
@@ -25,7 +25,7 @@ public class Chat implements EntityWithId {
@NotBlank
private String name;
- @OneToMany(mappedBy = "chat")
+ @OneToMany(mappedBy = "chat", orphanRemoval = true)
private Collection messages = new ArrayList<>();
@ManyToMany
diff --git a/server/src/main/java/com/usatiuk/tjv/y/server/entity/Person.java b/server/src/main/java/com/usatiuk/tjv/y/server/entity/Person.java
index bffe62a..81fcedd 100644
--- a/server/src/main/java/com/usatiuk/tjv/y/server/entity/Person.java
+++ b/server/src/main/java/com/usatiuk/tjv/y/server/entity/Person.java
@@ -34,13 +34,13 @@ public class Person implements EntityWithId {
@NotBlank(message = "Password can't be empty")
private String password;
- @OneToMany(mappedBy = "author")
+ @OneToMany(mappedBy = "author", orphanRemoval = true)
private Collection posts = new ArrayList<>();
- @OneToMany(mappedBy = "creator")
+ @OneToMany(mappedBy = "creator", orphanRemoval = true)
private Collection createdChats = new ArrayList<>();
- @OneToMany(mappedBy = "author")
+ @OneToMany(mappedBy = "author", orphanRemoval = true)
private Collection messages = new ArrayList<>();
@ManyToMany