added delete contact route
This commit is contained in:
17
.idea/dataSources.xml
generated
17
.idea/dataSources.xml
generated
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
||||
<data-source source="LOCAL" name="postgres@192.168.0.47" uuid="fc534921-0a7d-4120-bac3-e6f8ac7fb7a1">
|
||||
<driver-ref>postgresql</driver-ref>
|
||||
<synchronize>true</synchronize>
|
||||
<jdbc-driver>org.postgresql.Driver</jdbc-driver>
|
||||
<jdbc-url>jdbc:postgresql://192.168.0.47:5432/postgres</jdbc-url>
|
||||
<jdbc-additional-properties>
|
||||
<property name="com.intellij.clouds.kubernetes.db.host.port" />
|
||||
<property name="com.intellij.clouds.kubernetes.db.enabled" value="false" />
|
||||
<property name="com.intellij.clouds.kubernetes.db.container.port" />
|
||||
</jdbc-additional-properties>
|
||||
<working-dir>$ProjectFileDir$</working-dir>
|
||||
</data-source>
|
||||
</component>
|
||||
</project>
|
||||
2
.idea/sqldialects.xml
generated
2
.idea/sqldialects.xml
generated
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="SqlDialectMappings">
|
||||
<file url="file://$PROJECT_DIR$/database/db.go" dialect="GenericSQL" />
|
||||
<file url="file://$PROJECT_DIR$/database/auth.go" dialect="PostgreSQL" />
|
||||
<file url="PROJECT" dialect="PostgreSQL" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -52,6 +52,9 @@ func InsertUser(db *sql.DB, username string, passwordHash string) (string, error
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error inserting user: %v", err)
|
||||
}
|
||||
|
||||
log.Printf("Inserted user: %v", username)
|
||||
|
||||
return userId, err
|
||||
}
|
||||
|
||||
@@ -64,8 +67,8 @@ func GetPasswordHash(db *sql.DB, username string) (string, error) {
|
||||
var passwordHash string
|
||||
err := db.QueryRow(query, username).Scan(&passwordHash)
|
||||
if err != nil {
|
||||
fmt.Printf("error getting password: %v\n", err)
|
||||
return "", fmt.Errorf("error getting password: %v", err)
|
||||
fmt.Printf("error getting password hash: %v\n", err)
|
||||
return "", fmt.Errorf("error getting password hash: %v", err)
|
||||
}
|
||||
|
||||
return passwordHash, err
|
||||
88
database/contacts.go
Normal file
88
database/contacts.go
Normal file
@@ -0,0 +1,88 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/google/uuid"
|
||||
"log"
|
||||
)
|
||||
|
||||
func DeleteContact(db *sql.DB, userID uuid.UUID, conversationID uuid.UUID) (string, error) {
|
||||
// Check conversation type
|
||||
var conversationType string
|
||||
err := db.QueryRow(
|
||||
"SELECT conversation_type FROM Conversations WHERE conversation_id = $1",
|
||||
conversationID,
|
||||
).Scan(&conversationType)
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return "no conversation found for this id", nil
|
||||
}
|
||||
return "", fmt.Errorf("error checking conversation type: %w", err)
|
||||
}
|
||||
|
||||
if conversationType == "group" {
|
||||
// Delete from Contacts
|
||||
res, err := db.Exec(
|
||||
"DELETE FROM Contacts WHERE conversation_id = $1 AND user_id = $2",
|
||||
conversationID,
|
||||
userID,
|
||||
)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error deleting contact: %w", err)
|
||||
}
|
||||
|
||||
rowsAffected, err := res.RowsAffected()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error checking contact deletion: %w", err)
|
||||
}
|
||||
if rowsAffected == 0 {
|
||||
return fmt.Sprintf("no matching contact found with conversation id: %s, user id: %s", conversationID, userID), nil
|
||||
}
|
||||
|
||||
// Delete from Memberships
|
||||
res, err = db.Exec(
|
||||
"DELETE FROM Memberships WHERE conversation_id = $1 AND user_id = $2",
|
||||
conversationID,
|
||||
userID,
|
||||
)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error deleting membership: %w", err)
|
||||
}
|
||||
|
||||
rowsAffected, err = res.RowsAffected()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error checking membership deletion: %w", err)
|
||||
}
|
||||
if rowsAffected == 0 {
|
||||
return "", fmt.Errorf("no matching membership found with conversation id: %s, user id: %s", conversationID, userID)
|
||||
}
|
||||
|
||||
log.Printf("Successfully removed user %s from group %s", userID, conversationID)
|
||||
} else {
|
||||
// Handle direct conversation
|
||||
res, err := db.Exec(
|
||||
"DELETE FROM Contacts WHERE user_id = $1 AND conversation_id = $2",
|
||||
userID,
|
||||
conversationID,
|
||||
)
|
||||
if err != nil {
|
||||
log.Printf("Error deleting contact: %v", err)
|
||||
return "", fmt.Errorf("error deleting contact: %w", err)
|
||||
}
|
||||
|
||||
rowsAffected, err := res.RowsAffected()
|
||||
if err != nil {
|
||||
log.Printf("Error checking contact deletion: %v", err)
|
||||
return "", fmt.Errorf("error checking contact deletion: %w", err)
|
||||
}
|
||||
if rowsAffected == 0 {
|
||||
return fmt.Sprintf("no matching contact found with user id: %s, conversation id: %s", userID, conversationID), nil
|
||||
}
|
||||
|
||||
log.Printf("Successfully deleted contact for user %s in conversation %s", userID, conversationID)
|
||||
}
|
||||
|
||||
return "", nil
|
||||
}
|
||||
@@ -9,27 +9,34 @@ import (
|
||||
"relay-server/config"
|
||||
"relay-server/database"
|
||||
"relay-server/helpers"
|
||||
"relay-server/model"
|
||||
"time"
|
||||
)
|
||||
|
||||
func Signup(c *fiber.Ctx) error {
|
||||
|
||||
type SignupStruct struct {
|
||||
Username string `json:"username" xml:"username" form:"username"`
|
||||
Password string `json:"password" xml:"password" form:"password"`
|
||||
}
|
||||
|
||||
db := database.DB
|
||||
u := new(model.SignupStruct)
|
||||
u := new(SignupStruct)
|
||||
if err := c.BodyParser(u); err != nil {
|
||||
return err
|
||||
}
|
||||
// Checks if username or passwords are empty
|
||||
if u.Username == "" {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "username is empty"})
|
||||
} else if u.Password == "" {
|
||||
}
|
||||
if u.Password == "" {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "password is empty"})
|
||||
}
|
||||
|
||||
// Checks if passwords or username have valid length and characters
|
||||
if !helpers.IsValidPassword(u.Password) {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "invalid password"})
|
||||
} else if !helpers.IsValidUsername(u.Username) {
|
||||
}
|
||||
if !helpers.IsValidUsername(u.Username) {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "invalid username"})
|
||||
}
|
||||
|
||||
@@ -74,8 +81,14 @@ func Signup(c *fiber.Ctx) error {
|
||||
}
|
||||
|
||||
func Login(c *fiber.Ctx) error {
|
||||
|
||||
type loginStruct struct {
|
||||
Username string `json:"username" xml:"username" form:"username"`
|
||||
Password string `json:"password" xml:"password" form:"password"`
|
||||
}
|
||||
|
||||
db := database.DB
|
||||
u := new(model.LoginStruct)
|
||||
u := new(loginStruct)
|
||||
|
||||
if err := c.BodyParser(u); err != nil {
|
||||
return err
|
||||
@@ -84,14 +97,16 @@ func Login(c *fiber.Ctx) error {
|
||||
// Checks if username or passwords are empty
|
||||
if u.Username == "" {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "username is empty"})
|
||||
} else if u.Password == "" {
|
||||
}
|
||||
if u.Password == "" {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "password is empty"})
|
||||
}
|
||||
|
||||
// Checks if username or passwords have valid length and characters
|
||||
if !helpers.IsValidUsername(u.Username) {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "invalid username"})
|
||||
} else if !helpers.IsValidPassword(u.Password) {
|
||||
}
|
||||
if !helpers.IsValidPassword(u.Password) {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "invalid password"})
|
||||
}
|
||||
|
||||
|
||||
42
handlers/contacts.go
Normal file
42
handlers/contacts.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/google/uuid"
|
||||
"log"
|
||||
"relay-server/database"
|
||||
)
|
||||
|
||||
func DeleteContact(c *fiber.Ctx) error {
|
||||
|
||||
type params struct {
|
||||
ContactId uuid.UUID `params:"contact_id"`
|
||||
ConversationId uuid.UUID `params:"conversation_id"`
|
||||
}
|
||||
|
||||
p := new(params)
|
||||
if err := c.ParamsParser(p); err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid params"})
|
||||
}
|
||||
|
||||
db := database.DB
|
||||
|
||||
if p.ContactId == uuid.Nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"message": "contact_id is empty"})
|
||||
}
|
||||
if p.ConversationId == uuid.Nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"message": "conversation_id is empty"})
|
||||
}
|
||||
|
||||
msg, err := database.DeleteContact(db, p.ContactId, p.ConversationId)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Failed to delete contact"})
|
||||
}
|
||||
if msg != "" {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"message": msg})
|
||||
}
|
||||
log.Println("Contact deleted")
|
||||
|
||||
return c.Status(fiber.StatusOK).JSON(fiber.Map{"message": "Contact deleted"})
|
||||
}
|
||||
@@ -2,16 +2,6 @@ package model
|
||||
|
||||
import "github.com/golang-jwt/jwt/v5"
|
||||
|
||||
type LoginStruct struct {
|
||||
Username string `json:"username" xml:"username" form:"username"`
|
||||
Password string `json:"password" xml:"password" form:"password"`
|
||||
}
|
||||
|
||||
type SignupStruct struct {
|
||||
Username string `json:"username" xml:"username" form:"username"`
|
||||
Password string `json:"password" xml:"password" form:"password"`
|
||||
}
|
||||
|
||||
type UserClaims struct {
|
||||
Username string `json:"username"`
|
||||
UserId string `json:"user_id"`
|
||||
|
||||
@@ -12,10 +12,15 @@ func SetupRoutes(app *fiber.App) {
|
||||
return c.SendString("Hello, World!")
|
||||
})
|
||||
api := app.Group("/api", logger.New())
|
||||
chat := api.Group("/chat", middleware.Protected(), logger.New())
|
||||
|
||||
// Auth group
|
||||
auth := api.Group("/auth", middleware.Protected(), handlers.ValidateToken)
|
||||
auth.Post("/signup", handlers.Signup)
|
||||
auth.Post("/login", handlers.Login)
|
||||
auth.Get("/validate", handlers.ValidateToken)
|
||||
|
||||
// Contacts group
|
||||
contacts := chat.Group("/contacts", middleware.Protected(), logger.New())
|
||||
contacts.Delete("/:contact_id/:conversation_id", handlers.DeleteContact)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user