Index: springapp/src/main/java/mk/profesori/springapp/Controller/PublicController.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Controller/PublicController.java	(revision c68150fac8ab8e6f5dc5b8b2a9cd73d391dc1aa7)
+++ springapp/src/main/java/mk/profesori/springapp/Controller/PublicController.java	(revision 3b6962d804b15d4cf06da32490fdbafc33fe3ea5)
@@ -25,5 +25,5 @@
 @RestController
 @RequestMapping("/public")
-@CrossOrigin(origins = { "http://192.168.0.17:3000", "http://192.168.0.39:3000" })
+@CrossOrigin(origins = { "http://192.168.0.19:3000", "http://192.168.0.39:3000" })
 public class PublicController {
 
Index: springapp/src/main/java/mk/profesori/springapp/Controller/SecureController.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Controller/SecureController.java	(revision c68150fac8ab8e6f5dc5b8b2a9cd73d391dc1aa7)
+++ springapp/src/main/java/mk/profesori/springapp/Controller/SecureController.java	(revision 3b6962d804b15d4cf06da32490fdbafc33fe3ea5)
@@ -3,6 +3,9 @@
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import mk.profesori.springapp.Model.CustomUserDetails;
+import mk.profesori.springapp.Model.PostReport;
+import mk.profesori.springapp.Model.UserRole;
 import mk.profesori.springapp.Service.CustomUserDetailsService;
 import mk.profesori.springapp.Service.MainService;
+import org.apache.tomcat.websocket.AuthenticationException;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.annotation.CurrentSecurityContext;
@@ -11,12 +14,13 @@
 import org.springframework.web.bind.annotation.*;
 
+import java.util.List;
+
 @RestController
 @RequestMapping("/secure")
-@CrossOrigin(origins = { "http://192.168.0.17:3000", "http://192.168.0.39:3000" })
+@CrossOrigin(origins = { "http://192.168.0.19:3000", "http://192.168.0.39:3000" })
 public class SecureController {
 
     private final MainService mainService;
-    final
-    CustomUserDetailsService customUserDetailsService;
+    final CustomUserDetailsService customUserDetailsService;
 
     public SecureController(MainService mainService, CustomUserDetailsService customUserDetailsService) {
@@ -28,7 +32,5 @@
     public void addOpinion(@RequestBody ObjectNode objectNode, @PathVariable Long professorId,
             @CurrentSecurityContext SecurityContext context) {
-
-        Authentication authentication = context.getAuthentication();
-
+        Authentication authentication = context.getAuthentication();
         if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
             String content = objectNode.get("content").asText();
@@ -40,7 +42,5 @@
     public void replyToOpinion(@RequestBody ObjectNode objectNode, @PathVariable Long professorId,
             @PathVariable Long postId, @CurrentSecurityContext SecurityContext context) {
-
-        Authentication authentication = context.getAuthentication();
-
+        Authentication authentication = context.getAuthentication();
         if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
             String content = objectNode.get("content").asText();
@@ -52,7 +52,5 @@
     public void addThread(@RequestBody ObjectNode objectNode, @PathVariable Long subjectId,
             @CurrentSecurityContext SecurityContext context) {
-
-        Authentication authentication = context.getAuthentication();
-
+        Authentication authentication = context.getAuthentication();
         if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
             String title = objectNode.get("title").asText();
@@ -65,7 +63,5 @@
     public void replyToThread(@RequestBody ObjectNode objectNode, @PathVariable Long subjectId,
             @PathVariable Long postId, @CurrentSecurityContext SecurityContext context) {
-
-        Authentication authentication = context.getAuthentication();
-
+        Authentication authentication = context.getAuthentication();
         if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
             String content = objectNode.get("content").asText();
@@ -76,10 +72,8 @@
     @RequestMapping(value = "/currentUser", method = RequestMethod.GET)
     public UserDetails getUserDetails(@CurrentSecurityContext SecurityContext context) {
-
         Authentication authentication = context.getAuthentication();
         if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
             return customUserDetailsService.loadUserByUsername(currentUser.getEmail());
         }
-
         return null;
     }
@@ -87,7 +81,5 @@
     @RequestMapping(value = "/upvoteOpinion/{postId}", method = RequestMethod.GET)
     public void upvoteOpinion(@PathVariable Long postId, @CurrentSecurityContext SecurityContext context) {
-
-        Authentication authentication = context.getAuthentication();
-
+        Authentication authentication = context.getAuthentication();
         if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
             mainService.upvoteOpinion(postId, currentUser);
@@ -97,7 +89,5 @@
     @RequestMapping(value = "/downvoteOpinion/{postId}", method = RequestMethod.GET)
     public void downvoteOpinion(@PathVariable Long postId, @CurrentSecurityContext SecurityContext context) {
-
-        Authentication authentication = context.getAuthentication();
-
+        Authentication authentication = context.getAuthentication();
         if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
             mainService.downvoteOpinion(postId, currentUser);
@@ -107,7 +97,5 @@
     @RequestMapping(value = "/upvoteThread/{postId}", method = RequestMethod.GET)
     public void upvoteThread(@PathVariable Long postId, @CurrentSecurityContext SecurityContext context) {
-
-        Authentication authentication = context.getAuthentication();
-
+        Authentication authentication = context.getAuthentication();
         if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
             mainService.upvote_Thread(postId, currentUser);
@@ -119,5 +107,4 @@
 
         Authentication authentication = context.getAuthentication();
-
         if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
             mainService.downvote_Thread(postId, currentUser);
@@ -125,3 +112,132 @@
     }
 
+    @RequestMapping(value = "/deleteOpinion/{postId}", method = RequestMethod.DELETE)
+    public void deleteOpinion(@PathVariable Long postId, @CurrentSecurityContext SecurityContext context)
+            throws Exception {
+        Authentication authentication = context.getAuthentication();
+        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser
+                && currentUser.getUserRole().equals(UserRole.MODERATOR)) {
+            mainService.deleteOpinion(postId);
+        } else
+            throw new AuthenticationException("Auth exception");
+    }
+
+    @RequestMapping(value = "/deleteThread/{postId}", method = RequestMethod.DELETE)
+    public void deleteThread(@PathVariable Long postId, @CurrentSecurityContext SecurityContext context) {
+        Authentication authentication = context.getAuthentication();
+        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser
+                && currentUser.getUserRole().equals(UserRole.MODERATOR)) {
+            mainService.delete_Thread(postId);
+        }
+    }
+
+    @RequestMapping(value = "/updateOpinion/{postId}", method = RequestMethod.PUT)
+    public void updateOpinion(@RequestBody ObjectNode objectNode, @PathVariable Long postId,
+            @CurrentSecurityContext SecurityContext context) {
+        Authentication authentication = context.getAuthentication();
+        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser
+                && currentUser.getUserRole().equals(UserRole.MODERATOR)) {
+            String newContent = objectNode.get("newContent").asText();
+            Long newTargetProfessorId = objectNode.get("newTargetProfessorId").asLong();
+            mainService.updateOpinion(newContent, newTargetProfessorId, postId);
+        }
+    }
+
+    @RequestMapping(value = "/updateThread/{postId}", method = RequestMethod.PUT)
+    public void updateThread(@RequestBody ObjectNode objectNode, @PathVariable Long postId,
+            @CurrentSecurityContext SecurityContext context) {
+        Authentication authentication = context.getAuthentication();
+        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser
+                && currentUser.getUserRole().equals(UserRole.MODERATOR)) {
+            String newTitle = objectNode.get("newTitle").asText();
+            String newContent = objectNode.get("newContent").asText();
+            Long newTargetSubjectId = objectNode.get("newTargetSubjectId").asLong();
+
+            if (objectNode.has("newParentThreadId")) {
+                Long newParentThreadId = objectNode.get("newParentThreadId").asLong();
+                mainService.update_Thread(newTitle, newContent, newTargetSubjectId, newParentThreadId, postId);
+            } else {
+                mainService.update_Thread(newTitle, newContent, newTargetSubjectId, null, postId);
+            }
+        }
+    }
+
+    @RequestMapping(value = "/lockUser/{userId}", method = RequestMethod.GET)
+    public void lockUser(@PathVariable Long userId, @CurrentSecurityContext SecurityContext context) {
+        Authentication authentication = context.getAuthentication();
+        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser
+                && currentUser.getUserRole().equals(UserRole.MODERATOR)) {
+            mainService.lockUser(userId);
+        }
+    }
+
+    @RequestMapping(value = "/deleteUser/{userId}", method = RequestMethod.DELETE)
+    public void deleteUser(@PathVariable Long userId, @CurrentSecurityContext SecurityContext context) {
+        Authentication authentication = context.getAuthentication();
+        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser
+                && currentUser.getUserRole().equals(UserRole.MODERATOR)) {
+            mainService.deleteUser(userId);
+        }
+    }
+
+    @RequestMapping(value = "/updateUserFullName/{userId}", method = RequestMethod.PUT)
+    public void updateUserFullName(@RequestBody ObjectNode objectNode, @PathVariable Long userId,
+            @CurrentSecurityContext SecurityContext context) {
+        Authentication authentication = context.getAuthentication();
+        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser
+                && (currentUser.getUserRole().equals(UserRole.MODERATOR) || currentUser.getId().equals(userId))) {
+            String newFullName = objectNode.get("newFullName").asText();
+            mainService.updateUserFullName(newFullName, userId);
+        }
+    }
+
+    @RequestMapping(value = "/updateUserUsername/{userId}", method = RequestMethod.PUT)
+    public void updateUserUsername(@RequestBody ObjectNode objectNode, @PathVariable Long userId,
+            @CurrentSecurityContext SecurityContext context) {
+        Authentication authentication = context.getAuthentication();
+        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser
+                && (currentUser.getUserRole().equals(UserRole.MODERATOR) || currentUser.getId().equals(userId))) {
+            String newUsername = objectNode.get("newUsername").asText();
+            mainService.updateUserUsername(newUsername, userId);
+        }
+    }
+
+    @RequestMapping(value = "/reportOpinion/{postId}", method = RequestMethod.POST)
+    public void reportOpinion(@RequestBody ObjectNode objectNode, @PathVariable Long postId,
+                              @CurrentSecurityContext SecurityContext context) {
+        Authentication authentication = context.getAuthentication();
+        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
+            String description = objectNode.get("description").asText();
+            mainService.reportOpinion(postId, currentUser, description);
+        }
+    }
+
+    @RequestMapping(value = "/reportThread/{postId}", method = RequestMethod.POST)
+    public void reportThread(@RequestBody ObjectNode objectNode, @PathVariable Long postId,
+                              @CurrentSecurityContext SecurityContext context) {
+        Authentication authentication = context.getAuthentication();
+        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
+            String description = objectNode.get("description").asText();
+            mainService.reportThread(postId, currentUser, description);
+        }
+    }
+
+    @RequestMapping(value = "/markReportResolved/{postReportId}/", method = RequestMethod.GET)
+    public void markReportResolved(@PathVariable Long postReportId, @PathVariable String action, @CurrentSecurityContext SecurityContext context) {
+        Authentication authentication = context.getAuthentication();
+        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser) {
+            mainService.markReport(postReportId, action);
+        }
+    }
+
+    @RequestMapping(value = "/getAllPostReports", method = RequestMethod.GET)
+    public List<PostReport> getAllPostReports(@CurrentSecurityContext SecurityContext context) throws AuthenticationException{
+        Authentication authentication = context.getAuthentication();
+        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails currentUser
+                && currentUser.getUserRole().equals(UserRole.MODERATOR)) {
+            return mainService.getAllPostReports();
+        } else throw new AuthenticationException("Invalid role");
+     }
+
+
 }
Index: springapp/src/main/java/mk/profesori/springapp/Model/CustomUserDetails.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Model/CustomUserDetails.java	(revision c68150fac8ab8e6f5dc5b8b2a9cd73d391dc1aa7)
+++ springapp/src/main/java/mk/profesori/springapp/Model/CustomUserDetails.java	(revision 3b6962d804b15d4cf06da32490fdbafc33fe3ea5)
@@ -29,28 +29,29 @@
     @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_sequence")
     private Long id;
-    private String fullName; // opcionalno, smee da e prazno
+    private String fullName;
     private String username;
     private String email;
-    private String password; // TODO dont expose password in api
+    private String password; // TODO
     @Enumerated(EnumType.STRING)
     private UserRole userRole;
     private Boolean locked = false;
     private Boolean enabled = false;
-    @OneToMany(mappedBy = "customUserDetails", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
+    @OneToMany(mappedBy = "customUserDetails", fetch = FetchType.EAGER, orphanRemoval = true)
     private Set<ConfirmationToken> confirmationTokens = new HashSet<>();
-    @OneToMany(mappedBy = "author", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
+    @OneToMany(mappedBy = "author", fetch = FetchType.EAGER, orphanRemoval = true)
     private Set<Post> authoredPosts = new HashSet<>();
     private Integer karma = 0;
 
-    public Set<PostVote> getVotes() {
-        return votes;
+    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
+    private Set<PostVote> votes = new HashSet<>();
+
+    @OneToMany(mappedBy = "user", cascade = {CascadeType.PERSIST})
+    private Set<PostReport> reportsSubmitted = new HashSet<>();
+    @PreRemove
+    public void preRemove() {
+        reportsSubmitted.forEach(report -> {
+            report.setUser(null);
+        });
     }
-
-    public void setVotes(Set<PostVote> votes) {
-        this.votes = votes;
-    }
-
-    @OneToMany(mappedBy = "user")
-    private Set<PostVote> votes = new HashSet<>();
 
     public CustomUserDetails(String fullName, String username, String email, String password, UserRole userRole) {
@@ -115,3 +116,14 @@
     }
 
+    public void setLocked(Boolean locked) {
+        this.locked = locked;
+    }
+
+    public Set<PostVote> getVotes() {
+        return votes;
+    }
+
+    public void setVotes(Set<PostVote> votes) {
+        this.votes = votes;
+    }
 }
Index: springapp/src/main/java/mk/profesori/springapp/Model/Opinion.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Model/Opinion.java	(revision c68150fac8ab8e6f5dc5b8b2a9cd73d391dc1aa7)
+++ springapp/src/main/java/mk/profesori/springapp/Model/Opinion.java	(revision 3b6962d804b15d4cf06da32490fdbafc33fe3ea5)
@@ -40,7 +40,7 @@
         return targetProfessor;
     }
-
     public void setTargetProfessor(Professor targetProfessor) {
         this.targetProfessor = targetProfessor;
     }
+
 }
Index: springapp/src/main/java/mk/profesori/springapp/Model/Post.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Model/Post.java	(revision c68150fac8ab8e6f5dc5b8b2a9cd73d391dc1aa7)
+++ springapp/src/main/java/mk/profesori/springapp/Model/Post.java	(revision 3b6962d804b15d4cf06da32490fdbafc33fe3ea5)
@@ -1,4 +1,9 @@
 package mk.profesori.springapp.Model;
 
+import com.fasterxml.jackson.annotation.JsonIdentityInfo;
+import com.voodoodyne.jackson.jsog.JSOGGenerator;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
 import java.time.LocalDateTime;
 import java.util.ArrayList;
@@ -6,24 +11,4 @@
 import java.util.List;
 import java.util.Set;
-
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.DiscriminatorColumn;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.DiscriminatorType;
-import javax.persistence.InheritanceType;
-import javax.persistence.JoinColumn;
-import javax.persistence.ManyToMany;
-import javax.persistence.ManyToOne;
-import javax.persistence.OneToMany;
-
-import com.fasterxml.jackson.annotation.JsonIdentityInfo;
-import com.voodoodyne.jackson.jsog.JSOGGenerator;
-
-import lombok.NoArgsConstructor;
 
 @Entity(name = "post")
@@ -59,7 +44,22 @@
     private Post parent;
 
-    @OneToMany(mappedBy = "post")
+    @OneToMany(mappedBy = "post", cascade = CascadeType.ALL, orphanRemoval = true)
     private Set<PostVote> votes = new HashSet<>();
 
+    @OneToMany(mappedBy = "post", cascade={CascadeType.PERSIST})
+    private Set<PostReport> reports = new HashSet<>();
+    @PreRemove
+    public void preRemove() {
+        reports.forEach(report -> {
+            report.setPost(null);
+            report.setResolved(true);
+        });
+    }
+
+
+    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
+    private List<Post> children = new ArrayList<>();
+
+    // getters and setters
     public Set<PostVote> getVotes() {
         return votes;
@@ -69,9 +69,4 @@
         this.votes = votes;
     }
-
-    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
-    private List<Post> children = new ArrayList<>();
-
-    // getters and setters
     public Long getPostId() {
         return postId;
@@ -169,3 +164,4 @@
     }
 
+
 }
Index: springapp/src/main/java/mk/profesori/springapp/Model/PostReport.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Model/PostReport.java	(revision 3b6962d804b15d4cf06da32490fdbafc33fe3ea5)
+++ springapp/src/main/java/mk/profesori/springapp/Model/PostReport.java	(revision 3b6962d804b15d4cf06da32490fdbafc33fe3ea5)
@@ -0,0 +1,88 @@
+package mk.profesori.springapp.Model;
+
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+import java.time.LocalDateTime;
+
+@Entity
+@NoArgsConstructor
+public class PostReport {
+
+    @Id
+    @SequenceGenerator(name = "post_report_sequence", sequenceName = "post_report_sequence", allocationSize = 1)
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "post_report_sequence")
+    private Long postReportId;
+
+    @ManyToOne
+    @JoinColumn(name = "custom_user_details_id")
+    private CustomUserDetails user;
+
+    @ManyToOne
+    @JoinColumn(name = "post_id")
+    private Post post;
+
+    LocalDateTime time;
+
+    @Column(name = "description", columnDefinition = "TEXT")
+    private String description;
+
+    @Column(name = "resolved")
+    private boolean resolved;
+
+    public PostReport(CustomUserDetails user, Post post, String description) {
+        this.user = user;
+        this.post = post;
+        this.time = LocalDateTime.now();
+        this.description = description;
+        this.resolved=false;
+    }
+
+    public boolean isResolved() {
+        return resolved;
+    }
+
+    public void setResolved(boolean resolved) {
+        this.resolved = resolved;
+    }
+
+    public Long getPostReportId() {
+        return postReportId;
+    }
+
+    public void setPostReportId(Long postReportId) {
+        this.postReportId = postReportId;
+    }
+
+    public CustomUserDetails getUser() {
+        return user;
+    }
+
+    public void setUser(CustomUserDetails user) {
+        this.user = user;
+    }
+
+    public Post getPost() {
+        return post;
+    }
+
+    public void setPost(Post post) {
+        this.post = post;
+    }
+
+    public LocalDateTime getTime() {
+        return time;
+    }
+
+    public void setTime(LocalDateTime time) {
+        this.time = time;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+}
Index: springapp/src/main/java/mk/profesori/springapp/Model/_Thread.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Model/_Thread.java	(revision c68150fac8ab8e6f5dc5b8b2a9cd73d391dc1aa7)
+++ springapp/src/main/java/mk/profesori/springapp/Model/_Thread.java	(revision 3b6962d804b15d4cf06da32490fdbafc33fe3ea5)
@@ -41,3 +41,6 @@
     }
 
+    public void setTargetSubject(Subject targetSubject) {
+        this.targetSubject = targetSubject;
+    }
 }
Index: springapp/src/main/java/mk/profesori/springapp/Repository/CityRepository.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Repository/CityRepository.java	(revision c68150fac8ab8e6f5dc5b8b2a9cd73d391dc1aa7)
+++ springapp/src/main/java/mk/profesori/springapp/Repository/CityRepository.java	(revision 3b6962d804b15d4cf06da32490fdbafc33fe3ea5)
@@ -11,5 +11,5 @@
 public interface CityRepository extends CrudRepository<City, Long>{
 
-    public List<City> findAll();
-    public City findByCityId(Long id);
+    List<City> findAll();
+    City findByCityId(Long id);
 }
Index: springapp/src/main/java/mk/profesori/springapp/Repository/FacultyRepository.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Repository/FacultyRepository.java	(revision c68150fac8ab8e6f5dc5b8b2a9cd73d391dc1aa7)
+++ springapp/src/main/java/mk/profesori/springapp/Repository/FacultyRepository.java	(revision 3b6962d804b15d4cf06da32490fdbafc33fe3ea5)
@@ -12,6 +12,6 @@
 public interface FacultyRepository extends CrudRepository<Faculty, Long>{
 
-    public List<Faculty> findAll();
-    public Faculty findByFacultyId(Long id);
-    public List<Faculty> findByUniversity(University university);
+    List<Faculty> findAll();
+    Faculty findByFacultyId(Long id);
+    List<Faculty> findByUniversity(University university);
 }
Index: springapp/src/main/java/mk/profesori/springapp/Repository/PostReportRepository.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Repository/PostReportRepository.java	(revision 3b6962d804b15d4cf06da32490fdbafc33fe3ea5)
+++ springapp/src/main/java/mk/profesori/springapp/Repository/PostReportRepository.java	(revision 3b6962d804b15d4cf06da32490fdbafc33fe3ea5)
@@ -0,0 +1,13 @@
+package mk.profesori.springapp.Repository;
+
+import mk.profesori.springapp.Model.PostReport;
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface PostReportRepository extends CrudRepository<PostReport,Long> {
+    PostReport findByPostReportId(Long id);
+    List<PostReport> findAll();
+}
Index: springapp/src/main/java/mk/profesori/springapp/Repository/ProfessorRepository.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Repository/ProfessorRepository.java	(revision c68150fac8ab8e6f5dc5b8b2a9cd73d391dc1aa7)
+++ springapp/src/main/java/mk/profesori/springapp/Repository/ProfessorRepository.java	(revision 3b6962d804b15d4cf06da32490fdbafc33fe3ea5)
@@ -13,10 +13,10 @@
 public interface ProfessorRepository extends CrudRepository<Professor, Long>, JpaSpecificationExecutor<Professor> {
 
-    public List<Professor> findAll();
+    List<Professor> findAll();
 
-    public Professor findByProfessorId(Long id);
+    Professor findByProfessorId(Long id);
 
-    public List<Professor> findByFaculty(Faculty faculty);
+    List<Professor> findByFaculty(Faculty faculty);
 
-    public List<Professor> findByProfessorNameContainingIgnoreCase(String name);
+    List<Professor> findByProfessorNameContainingIgnoreCase(String name);
 }
Index: springapp/src/main/java/mk/profesori/springapp/Repository/StudyProgrammeRepository.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Repository/StudyProgrammeRepository.java	(revision c68150fac8ab8e6f5dc5b8b2a9cd73d391dc1aa7)
+++ springapp/src/main/java/mk/profesori/springapp/Repository/StudyProgrammeRepository.java	(revision 3b6962d804b15d4cf06da32490fdbafc33fe3ea5)
@@ -13,6 +13,6 @@
 public interface StudyProgrammeRepository extends CrudRepository<StudyProgramme, Long>{
     
-    public List<StudyProgramme> findAll();
-    public StudyProgramme findByStudyProgrammeId(Long id);
-    public List<StudyProgramme> findByFaculty(Faculty faculty);
+    List<StudyProgramme> findAll();
+    StudyProgramme findByStudyProgrammeId(Long id);
+    List<StudyProgramme> findByFaculty(Faculty faculty);
 }
Index: springapp/src/main/java/mk/profesori/springapp/Repository/SubjectRepository.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Repository/SubjectRepository.java	(revision c68150fac8ab8e6f5dc5b8b2a9cd73d391dc1aa7)
+++ springapp/src/main/java/mk/profesori/springapp/Repository/SubjectRepository.java	(revision 3b6962d804b15d4cf06da32490fdbafc33fe3ea5)
@@ -8,4 +8,4 @@
 @Repository
 public interface SubjectRepository extends CrudRepository<Subject, Long> {
-    public Subject findBySubjectId(Long id);
+    Subject findBySubjectId(Long id);
 }
Index: springapp/src/main/java/mk/profesori/springapp/Repository/UniversityRepository.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Repository/UniversityRepository.java	(revision c68150fac8ab8e6f5dc5b8b2a9cd73d391dc1aa7)
+++ springapp/src/main/java/mk/profesori/springapp/Repository/UniversityRepository.java	(revision 3b6962d804b15d4cf06da32490fdbafc33fe3ea5)
@@ -12,8 +12,8 @@
 public interface UniversityRepository extends CrudRepository<University, Long> {
 
-    public List<University> findAll();
+    List<University> findAll();
 
-    public University findByUniversityId(Long id);
+    University findByUniversityId(Long id);
 
-    public List<University> findByCity(City city);
+    List<University> findByCity(City city);
 }
Index: springapp/src/main/java/mk/profesori/springapp/Security/SecurityConfiguration.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Security/SecurityConfiguration.java	(revision c68150fac8ab8e6f5dc5b8b2a9cd73d391dc1aa7)
+++ springapp/src/main/java/mk/profesori/springapp/Security/SecurityConfiguration.java	(revision 3b6962d804b15d4cf06da32490fdbafc33fe3ea5)
@@ -37,5 +37,5 @@
             @Override
             public void addCorsMappings(CorsRegistry registry) {
-                registry.addMapping("/**").allowedOrigins("http://192.168.0.17:3000", "http://192.168.0.39:3000")
+                registry.addMapping("/**").allowedOrigins("http://192.168.0.19:3000", "http://192.168.0.39:3000")
                         .allowCredentials(true);
             }
Index: springapp/src/main/java/mk/profesori/springapp/Service/CustomUserDetailsService.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Service/CustomUserDetailsService.java	(revision c68150fac8ab8e6f5dc5b8b2a9cd73d391dc1aa7)
+++ springapp/src/main/java/mk/profesori/springapp/Service/CustomUserDetailsService.java	(revision 3b6962d804b15d4cf06da32490fdbafc33fe3ea5)
@@ -43,7 +43,5 @@
         userRepository.save(customUserDetails);
 
-        String token = createToken(customUserDetails);
-
-        return token;
+        return createToken(customUserDetails);
     }
 
@@ -60,6 +58,6 @@
     }
 
-    public int enableUser(String email) {
-        return userRepository.enableUser(email);
+    public void enableUser(String email) {
+        userRepository.enableUser(email);
     }
 }
Index: springapp/src/main/java/mk/profesori/springapp/Service/MainService.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Service/MainService.java	(revision c68150fac8ab8e6f5dc5b8b2a9cd73d391dc1aa7)
+++ springapp/src/main/java/mk/profesori/springapp/Service/MainService.java	(revision 3b6962d804b15d4cf06da32490fdbafc33fe3ea5)
@@ -3,6 +3,8 @@
 import mk.profesori.springapp.Model.*;
 import mk.profesori.springapp.Repository.*;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
 import org.springframework.stereotype.Service;
 
+import java.time.LocalDateTime;
 import java.util.ArrayList;
 import java.util.List;
@@ -21,6 +23,7 @@
     private final PostVoteRepository postVoteRepository;
     private final UserRepository userRepository;
-
-    public MainService(ProfessorRepository professorRepository, StudyProgrammeRepository studyProgrammeRepository, FacultyRepository facultyRepository, UniversityRepository universityRepository, CityRepository cityRepository, OpinionRepository opinionRepository, _ThreadRepository _threadRepository, SubjectRepository subjectRepository, PostVoteRepository postVoteRepository, UserRepository userRepository) {
+    private final PostReportRepository postReportRepository;
+
+    public MainService(ProfessorRepository professorRepository, StudyProgrammeRepository studyProgrammeRepository, FacultyRepository facultyRepository, UniversityRepository universityRepository, CityRepository cityRepository, OpinionRepository opinionRepository, _ThreadRepository _threadRepository, SubjectRepository subjectRepository, PostVoteRepository postVoteRepository, UserRepository userRepository, PostReportRepository postReportRepository) {
         this.professorRepository = professorRepository;
         this.studyProgrammeRepository = studyProgrammeRepository;
@@ -33,4 +36,5 @@
         this.postVoteRepository = postVoteRepository;
         this.userRepository = userRepository;
+        this.postReportRepository = postReportRepository;
     }
 
@@ -183,5 +187,4 @@
         targetPost.getAuthor().setKarma(targetPost.getAuthor().getKarma()+1);
         userRepository.save(targetPost.getAuthor());
-
     }
     public void downvote_Thread(Long postId, CustomUserDetails currentUser) {
@@ -192,3 +195,99 @@
         userRepository.save(targetPost.getAuthor());
     }
+
+    public void deleteOpinion(Long postId) {opinionRepository.deleteById(postId);}
+    public void delete_Thread(Long postId) {_threadRepository.deleteById(postId);}
+
+    public void updateOpinion(String newContent, Long newTargetProfessorId, Long postId) {
+        Opinion opinionToUpdate = opinionRepository.findByPostId(postId);
+
+        opinionToUpdate.setContent(newContent);
+
+        Professor newTargetProfessor = professorRepository.findByProfessorId(newTargetProfessorId);
+        opinionToUpdate.setTargetProfessor(newTargetProfessor); //opcijava da ja dava samo kaj postovi so parentPost==null
+        for(Post p : opinionToUpdate.getChildren()) {
+            Opinion o = (Opinion) p;
+            o.setTargetProfessor(newTargetProfessor);
+        }
+        opinionToUpdate.setTimeLastEdited(LocalDateTime.now());
+        opinionRepository.save(opinionToUpdate);
+    }
+
+    public void update_Thread(String newTitle, String newContent, Long newTargetSubjectId, Long newParentThreadId, Long postId) {
+        _Thread _threadToUpdate = _threadRepository.findByPostId(postId);
+
+        _threadToUpdate.setContent(newContent);
+
+        Subject newTargetSubject = subjectRepository.findBySubjectId(newTargetSubjectId);
+        _threadToUpdate.setTargetSubject(newTargetSubject);
+
+        if(newParentThreadId != null) { //samo ako e specificirano
+            _Thread newParentThread = _threadRepository.findByPostId(newParentThreadId);
+
+            if (_threadToUpdate.getParent() == null || _threadToUpdate.getParent().getPostId().equals(postId)) {
+                _threadToUpdate.setParent(newParentThread);
+            }//samo ako e naslovniot post ili directChild
+            } else if(_threadToUpdate.getParent() != null) {
+            _threadToUpdate.setParent(null);
+            }
+
+            if(_threadToUpdate.getParent() == null) {
+             _threadToUpdate.setTitle(newTitle);
+            } else {
+             _threadToUpdate.setTitle(null);
+             }
+
+         for(Post p : _threadToUpdate.getChildren()) {
+                _Thread t = (_Thread) p;
+                t.setTargetSubject(newTargetSubject);
+            }
+         _threadToUpdate.setTimeLastEdited(LocalDateTime.now());
+          _threadRepository.save(_threadToUpdate);
+    }
+
+    public void lockUser(Long userId) {
+        CustomUserDetails user = userRepository.findById(userId).orElseThrow(() -> new UsernameNotFoundException("Invalid userId"));
+        user.setLocked(true);
+        userRepository.save(user);
+    }
+
+    public void deleteUser(Long userId) {
+        userRepository.deleteById(userId);
+    }
+
+
+    public void updateUserFullName(String newFullName, Long userId) {
+        CustomUserDetails user = userRepository.findById(userId).orElseThrow(() -> new UsernameNotFoundException("Invalid userId"));
+        user.setFullName(newFullName);
+        userRepository.save(user);
+    }
+
+    public void updateUserUsername(String newUsername, Long userId) {
+        CustomUserDetails user = userRepository.findById(userId).orElseThrow(() -> new UsernameNotFoundException("Invalid userId"));
+        user.setUsername(newUsername);
+        userRepository.save(user);
+    }
+
+
+    public void reportOpinion(Long postId, CustomUserDetails currentUser, String description) {
+            Post targetPost = opinionRepository.findByPostId(postId);
+            PostReport reportToAdd = new PostReport(currentUser, targetPost, description);
+            postReportRepository.save(reportToAdd);
+    }
+
+    public void markReport(Long postReportId, String action) {
+        PostReport report = postReportRepository.findByPostReportId(postReportId);
+        if (action.equals("resolve")) report.setResolved(true);
+        else if (action.equals("open")) report.setResolved(false);
+     }
+
+    public List<PostReport> getAllPostReports() {
+        return postReportRepository.findAll();
+    }
+
+    public void reportThread(Long postId, CustomUserDetails currentUser, String description) {
+        Post targetPost = _threadRepository.findByPostId(postId);
+        PostReport reportToAdd = new PostReport(currentUser, targetPost, description);
+        postReportRepository.save(reportToAdd);
+    }
 }
Index: springapp/src/main/java/mk/profesori/springapp/Service/RegistrationService.java
===================================================================
--- springapp/src/main/java/mk/profesori/springapp/Service/RegistrationService.java	(revision c68150fac8ab8e6f5dc5b8b2a9cd73d391dc1aa7)
+++ springapp/src/main/java/mk/profesori/springapp/Service/RegistrationService.java	(revision 3b6962d804b15d4cf06da32490fdbafc33fe3ea5)
@@ -45,5 +45,5 @@
                 String tokenToResend = customUserDetailsService
                         .createToken(userRepository.findByEmail(request.getEmail()).get());
-                String link = "http://192.168.0.17:8080/registration/confirm?token=" + tokenToResend;
+                String link = "http://192.168.0.19:8080/registration/confirm?token=" + tokenToResend;
                 emailSender.send(request.getEmail(), emailSender.buildEmail(request.getUsername(), link));
                 return tokenToResend;
@@ -66,5 +66,5 @@
                         UserRole.REGULAR));
 
-        String link = "http://192.168.0.17:8080/registration/confirm?token=" + token;
+        String link = "http://192.168.0.19:8080/registration/confirm?token=" + token;
 
         emailSender.send(request.getEmail(), emailSender.buildEmail(request.getUsername(), link));
Index: springapp/src/main/resources/application.properties
===================================================================
--- springapp/src/main/resources/application.properties	(revision c68150fac8ab8e6f5dc5b8b2a9cd73d391dc1aa7)
+++ springapp/src/main/resources/application.properties	(revision 3b6962d804b15d4cf06da32490fdbafc33fe3ea5)
@@ -7,6 +7,6 @@
 spring.jpa.show-sql=false
 spring.jpa.properties.hibernate.format_sql=true
-server.address=192.168.0.17
-spring.mail.host=192.168.0.39
+server.address=192.168.0.19
+spring.mail.host=localhost
 spring.mail.username=mailuser
 spring.mail.password=mailpass
