😊🔫
This commit is contained in:
@@ -33,7 +33,7 @@ function ContactForm({ InitializeContact, setContactsList }: ContactFormProps) {
|
||||
|
||||
console.log(response.data);
|
||||
const { contact_user_id, contact_id } = response.data;
|
||||
|
||||
console.log('sdfjkljklsdfjklfdjklsdfjklsdf', response.data);
|
||||
InitializeContact(contact);
|
||||
|
||||
setContactsList((prevContacts) => {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import Cookies from 'js-cookie';
|
||||
import { axiosClient } from '../App.tsx';
|
||||
|
||||
function useAuth() {
|
||||
const [authorized, setAuthorized] = useState<boolean>(false);
|
||||
|
||||
|
||||
336
server/db/db.js
336
server/db/db.js
@@ -70,13 +70,13 @@ async function createTables() {
|
||||
CREATE TABLE IF NOT EXISTS Messages (
|
||||
message_id SERIAL PRIMARY KEY,
|
||||
conversation_id INT REFERENCES Conversations(conversation_id) ON DELETE CASCADE,
|
||||
sender_id INT REFERENCES Accounts(user_id) ON DELETE CASCADE,
|
||||
user_id INT REFERENCES Accounts(user_id) ON DELETE CASCADE,
|
||||
content TEXT NOT NULL,
|
||||
attachment_url TEXT,
|
||||
sent_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_messages_conversation_id ON Messages (conversation_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_messages_sender_id ON Messages (sender_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_messages_user_id ON Messages (user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_messages_conversation_sent_at ON Messages (conversation_id, sent_at);
|
||||
`);
|
||||
} catch (e) {
|
||||
@@ -104,14 +104,14 @@ async function createTables() {
|
||||
await client.query(`
|
||||
CREATE TABLE IF NOT EXISTS Contacts (
|
||||
contact_id SERIAL PRIMARY KEY,
|
||||
sender_id INT REFERENCES Accounts(user_id) ON DELETE CASCADE,
|
||||
receiver_id INT REFERENCES Accounts(user_id) ON DELETE CASCADE,
|
||||
user_id INT REFERENCES Accounts(user_id) ON DELETE CASCADE,
|
||||
contact_user_id INT REFERENCES Accounts(user_id) ON DELETE CASCADE,
|
||||
read BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
last_active TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT unique_contact UNIQUE (sender_id, receiver_id)
|
||||
CONSTRAINT unique_contact UNIQUE (user_id, contact_user_id)
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_contacts_sender_id ON Contacts (sender_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_contacts_receiver_id ON Contacts (receiver_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_contacts_user_id ON Contacts (user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_contacts_contact_user_id ON Contacts (contact_user_id);
|
||||
`);
|
||||
console.log("Contacts table created successfully.");
|
||||
} catch (e) {
|
||||
@@ -152,36 +152,92 @@ async function getUserId(username) {
|
||||
}
|
||||
}
|
||||
|
||||
async function insertMessage(sender_id, recipient_id, content, attachmentUrl) {
|
||||
async function insertMessage(
|
||||
senderUsername,
|
||||
receiverUsername,
|
||||
content,
|
||||
attachmentUrl,
|
||||
) {
|
||||
const query = `
|
||||
WITH sender AS (
|
||||
SELECT user_id
|
||||
FROM Accounts
|
||||
WHERE username = $1
|
||||
),
|
||||
recipient AS (
|
||||
SELECT user_id
|
||||
FROM Accounts
|
||||
WHERE username = $2
|
||||
),
|
||||
conversation AS (
|
||||
SELECT conversation_id
|
||||
FROM Conversations
|
||||
WHERE conversation_type = 'direct'
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM Memberships
|
||||
WHERE conversation_id = Conversations.conversation_id
|
||||
AND user_id = (SELECT user_id FROM sender)
|
||||
)
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM Memberships
|
||||
WHERE conversation_id = Conversations.conversation_id
|
||||
AND user_id = (SELECT user_id FROM recipient)
|
||||
)
|
||||
LIMIT 1
|
||||
),
|
||||
new_conversation AS (
|
||||
INSERT INTO Conversations (conversation_type)
|
||||
SELECT 'direct'
|
||||
WHERE NOT EXISTS (SELECT 1 FROM conversation)
|
||||
RETURNING conversation_id
|
||||
),
|
||||
final_conversation AS (
|
||||
SELECT conversation_id FROM conversation
|
||||
UNION ALL
|
||||
SELECT conversation_id FROM new_conversation
|
||||
),
|
||||
insert_memberships AS (
|
||||
INSERT INTO Memberships (conversation_id, user_id)
|
||||
SELECT conversation_id, user_id
|
||||
FROM final_conversation, sender
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM Memberships
|
||||
WHERE conversation_id = final_conversation.conversation_id
|
||||
AND user_id = sender.user_id
|
||||
)
|
||||
UNION ALL
|
||||
SELECT conversation_id, user_id
|
||||
FROM final_conversation, recipient
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM Memberships
|
||||
WHERE conversation_id = final_conversation.conversation_id
|
||||
AND user_id = recipient.user_id
|
||||
)
|
||||
)
|
||||
INSERT INTO Messages (conversation_id, sender_id, content, attachment_url)
|
||||
SELECT $1, sender.user_id, $3, $4
|
||||
FROM sender
|
||||
INSERT INTO Messages (conversation_id, user_id, content, attachment_url)
|
||||
SELECT conversation_id, sender.user_id, $3, $4
|
||||
FROM final_conversation, sender
|
||||
RETURNING message_id, content, sent_at, attachment_url;
|
||||
`;
|
||||
|
||||
try {
|
||||
const conversation_id = await getOrCreateConversation(
|
||||
sender_id,
|
||||
recipient_id,
|
||||
);
|
||||
const results = await client.query(query, [
|
||||
conversation_id,
|
||||
sender_id,
|
||||
const result = await client.query(query, [
|
||||
senderUsername,
|
||||
receiverUsername,
|
||||
content,
|
||||
attachmentUrl,
|
||||
]);
|
||||
return results.rows[0];
|
||||
return result.rows[0];
|
||||
} catch (e) {
|
||||
console.error("Failed to insert message ", e);
|
||||
}
|
||||
}
|
||||
|
||||
async function getOrCreateConversation(sender_id, recipient_id) {
|
||||
async function getOrCreateConversation(senderUsername, receiverUsername) {
|
||||
// Check if a conversation between these two users already exists
|
||||
const query = `
|
||||
SELECT conversation_id
|
||||
@@ -202,19 +258,22 @@ async function getOrCreateConversation(sender_id, recipient_id) {
|
||||
LIMIT 1;
|
||||
`;
|
||||
try {
|
||||
const result = await client.query(query, [sender_id, recipient_id]);
|
||||
const result = await client.query(query, [
|
||||
senderUsername,
|
||||
receiverUsername,
|
||||
]);
|
||||
if (result.rows.length > 0) {
|
||||
return result.rows[0].conversation_id;
|
||||
} else {
|
||||
// Create a new conversation
|
||||
return await createConversation(sender_id, recipient_id);
|
||||
return await createConversation(senderUsername, receiverUsername);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Failed to get or create conversation ", e);
|
||||
}
|
||||
}
|
||||
|
||||
async function createConversation(sender_id, recipient_id) {
|
||||
async function createConversation(senderUsername, receiverUsername) {
|
||||
const query = `
|
||||
INSERT INTO Conversations (conversation_type)
|
||||
VALUES ('direct')
|
||||
@@ -230,7 +289,7 @@ async function createConversation(sender_id, recipient_id) {
|
||||
INSERT INTO Memberships (conversation_id, user_id)
|
||||
VALUES ($1, (SELECT user_id FROM Accounts WHERE username = $2)), ($1, $3);
|
||||
`,
|
||||
[conversation_id, sender_id, recipient_id],
|
||||
[conversation_id, senderUsername, receiverUsername],
|
||||
);
|
||||
|
||||
return conversation_id;
|
||||
@@ -239,30 +298,86 @@ async function createConversation(sender_id, recipient_id) {
|
||||
}
|
||||
}
|
||||
|
||||
async function getMessages(sender_id, recipient_id, limit = 50, cursor = 0) {
|
||||
console.log(
|
||||
`getMessages for sender_id: ${sender_id}, recipient_id: ${recipient_id}, limit: ${limit}, cursor: ${cursor}`,
|
||||
);
|
||||
let query;
|
||||
let params;
|
||||
async function getMessages(
|
||||
senderUsername,
|
||||
receiverUsername,
|
||||
limit = 50,
|
||||
cursor = 0,
|
||||
) {
|
||||
let query = `
|
||||
WITH sender AS (
|
||||
SELECT user_id
|
||||
FROM Accounts
|
||||
WHERE username = $1
|
||||
),
|
||||
recipient AS (
|
||||
SELECT user_id
|
||||
FROM Accounts
|
||||
WHERE username = $2
|
||||
),
|
||||
conversation AS (
|
||||
SELECT conversation_id
|
||||
FROM Conversations
|
||||
WHERE conversation_type = 'direct'
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM Memberships
|
||||
WHERE conversation_id = Conversations.conversation_id
|
||||
AND user_id = (SELECT user_id FROM sender)
|
||||
)
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM Memberships
|
||||
WHERE conversation_id = Conversations.conversation_id
|
||||
AND user_id = (SELECT user_id FROM recipient)
|
||||
)
|
||||
LIMIT 1
|
||||
)
|
||||
SELECT * FROM Messages
|
||||
WHERE conversation_id = (SELECT conversation_id FROM conversation)
|
||||
AND message_id < $3
|
||||
ORDER BY message_id DESC
|
||||
LIMIT $4;
|
||||
`;
|
||||
|
||||
if (cursor) {
|
||||
let params = [senderUsername, receiverUsername, cursor, limit];
|
||||
|
||||
if (!cursor) {
|
||||
query = `
|
||||
WITH sender AS (
|
||||
SELECT user_id
|
||||
FROM Accounts
|
||||
WHERE username = $1
|
||||
),
|
||||
recipient AS (
|
||||
SELECT user_id
|
||||
FROM Accounts
|
||||
WHERE username = $2
|
||||
),
|
||||
conversation AS (
|
||||
SELECT conversation_id
|
||||
FROM Conversations
|
||||
WHERE conversation_type = 'direct'
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM Memberships
|
||||
WHERE conversation_id = Conversations.conversation_id
|
||||
AND user_id = (SELECT user_id FROM sender)
|
||||
)
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM Memberships
|
||||
WHERE conversation_id = Conversations.conversation_id
|
||||
AND user_id = (SELECT user_id FROM recipient)
|
||||
)
|
||||
LIMIT 1
|
||||
)
|
||||
SELECT * FROM Messages
|
||||
WHERE conversation_id = $1
|
||||
AND message_id < $2
|
||||
WHERE conversation_id = (SELECT conversation_id FROM conversation)
|
||||
ORDER BY message_id DESC
|
||||
LIMIT $3;
|
||||
`;
|
||||
params = [await getConversationId(sender_id, recipient_id), cursor, limit];
|
||||
} else {
|
||||
query = `
|
||||
SELECT * FROM Messages
|
||||
WHERE conversation_id = $1
|
||||
ORDER BY message_id DESC
|
||||
LIMIT $2;
|
||||
`;
|
||||
params = [await getConversationId(sender_id, recipient_id), limit];
|
||||
params = [senderUsername, receiverUsername, limit];
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -278,9 +393,9 @@ async function getMessages(sender_id, recipient_id, limit = 50, cursor = 0) {
|
||||
}
|
||||
}
|
||||
|
||||
async function getConversationId(sender_id, recipient_id) {
|
||||
async function getConversationId(senderUsername, receiverUsername) {
|
||||
console.log(
|
||||
`kldsdfjklsdfjklsdjfkl , sender_id: ${sender_id}, recipient_id: ${recipient_id}`,
|
||||
`kldsdfjklsdfjklsdjfkl , senderUsername: ${senderUsername}, receiverUsername: ${receiverUsername}`,
|
||||
);
|
||||
const query = `
|
||||
SELECT conversation_id FROM Conversations
|
||||
@@ -294,8 +409,11 @@ async function getConversationId(sender_id, recipient_id) {
|
||||
LIMIT 1;
|
||||
`;
|
||||
try {
|
||||
const result = await client.query(query, [sender_id, recipient_id]);
|
||||
if (result.rows.length > 0) {
|
||||
const result = await client.query(query, [
|
||||
senderUsername,
|
||||
receiverUsername,
|
||||
]);
|
||||
if (result.rowCount > 0) {
|
||||
return result.rows[0].conversation_id;
|
||||
} else {
|
||||
console.log("No conversation found between these users.");
|
||||
@@ -354,133 +472,101 @@ async function changePassword(username, newPasswordHash) {
|
||||
}
|
||||
}
|
||||
|
||||
async function insertContact(sender_id, receiverUsername, read) {
|
||||
const timestamp = getTime();
|
||||
console.log(
|
||||
`insertContact sender_id: ${sender_id}, receiverUsername: ${receiverUsername}, read: ${read}`,
|
||||
);
|
||||
|
||||
async function insertContact(userUsername, receiverUsername, read) {
|
||||
const query = `
|
||||
WITH user_check AS (
|
||||
SELECT user_id AS receiver_id
|
||||
FROM Accounts
|
||||
WHERE username = $2
|
||||
LIMIT 1
|
||||
),
|
||||
inserted_contact AS (
|
||||
INSERT INTO Contacts (sender_id, receiver_id, last_active, read)
|
||||
SELECT $1, uc.receiver_id, $3, $4
|
||||
FROM user_check uc
|
||||
ON CONFLICT ON CONSTRAINT unique_contact
|
||||
DO NOTHING
|
||||
RETURNING contact_id, receiver_id
|
||||
)
|
||||
SELECT i.contact_id, i.receiver_id AS contact_user_id
|
||||
FROM inserted_contact i;
|
||||
INSERT INTO Contacts (user_id, contact_user_id, read, last_active)
|
||||
VALUES
|
||||
((SELECT user_id FROM Accounts WHERE username = $1),
|
||||
(SELECT user_id FROM Accounts WHERE username = $2),
|
||||
$3,
|
||||
CURRENT_TIMESTAMP),
|
||||
((SELECT user_id FROM Accounts WHERE username = $2),
|
||||
(SELECT user_id FROM Accounts WHERE username = $1),
|
||||
$3,
|
||||
CURRENT_TIMESTAMP)
|
||||
ON CONFLICT DO NOTHING;
|
||||
`;
|
||||
|
||||
try {
|
||||
const result = await client.query(query, [
|
||||
sender_id,
|
||||
receiverUsername,
|
||||
timestamp,
|
||||
read,
|
||||
]);
|
||||
|
||||
if (result.rows.length > 0) {
|
||||
return result.rows[0];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
await client.query(query, [userUsername, receiverUsername, read]);
|
||||
} catch (e) {
|
||||
console.error("Failed to insert contact ", e);
|
||||
throw e;
|
||||
console.error("Failed to insert contact:", e);
|
||||
}
|
||||
}
|
||||
|
||||
async function getContacts(user_id) {
|
||||
//TODO ujednolicic te contact_id contact_user_id bo w bazie sa tabele z innymi nazwami a zwraca co innego
|
||||
async function getContacts(userUsername) {
|
||||
const query = `
|
||||
SELECT
|
||||
c.contact_id,
|
||||
CASE
|
||||
WHEN c.sender_id = $1 THEN c.receiver_id
|
||||
ELSE c.sender_id
|
||||
END AS contact_user_id,
|
||||
a.username as contact_username,
|
||||
c.read,
|
||||
c.last_active
|
||||
FROM Contacts c
|
||||
JOIN Accounts a ON (
|
||||
CASE
|
||||
WHEN c.sender_id = $1 THEN a.user_id = c.receiver_id
|
||||
ELSE a.user_id = c.sender_id
|
||||
END
|
||||
)
|
||||
WHERE c.sender_id = $1 OR c.receiver_id = $1
|
||||
ORDER BY c.last_active DESC;
|
||||
`;
|
||||
SELECT
|
||||
c.contact_id,
|
||||
c.contact_user_id,
|
||||
a.username AS contact_username,
|
||||
c.last_active
|
||||
FROM Contacts c
|
||||
JOIN Accounts a ON a.user_id = c.contact_user_id
|
||||
WHERE c.user_id = $1
|
||||
ORDER BY c.last_active DESC;
|
||||
`;
|
||||
|
||||
try {
|
||||
const result = await client.query(query, [user_id]);
|
||||
console.log("getcontacts: ", result.rows);
|
||||
const result = await client.query(query, [userUsername]);
|
||||
return result.rows;
|
||||
} catch (e) {
|
||||
console.error("Failed to get contacts ", e);
|
||||
console.error("Failed to get contacts:", e);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteContact(user_id, contact_id) {
|
||||
async function deleteContact(userUsername, contactUsername) {
|
||||
const query = `
|
||||
DELETE FROM Contacts
|
||||
WHERE sender_id = $1 AND contact_id = $2
|
||||
RETURNING *;
|
||||
WHERE (user_id = $1 AND contact_user_id = $2)
|
||||
OR (user_id = $2 AND contact_user_id = $1);
|
||||
`;
|
||||
|
||||
try {
|
||||
const result = await client.query(query, [user_id, contact_id]);
|
||||
const result = await client.query(query, [userUsername, contactUsername]);
|
||||
if (result.rowCount === 0) {
|
||||
console.log("No matching contact found with:", {
|
||||
user_id,
|
||||
contact_id,
|
||||
userUsername,
|
||||
contactUsername,
|
||||
});
|
||||
} else {
|
||||
console.log("Successfully deleted contact");
|
||||
console.log("Successfully deleted contact for: ", contactUsername);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Failed to remove contact ", e);
|
||||
}
|
||||
}
|
||||
|
||||
async function updateContactStatus(user_id, receiver_id, read) {
|
||||
async function updateContactStatus(userUsername, contact_user_id, read) {
|
||||
const query = `
|
||||
WITH users AS (
|
||||
SELECT
|
||||
(SELECT user_id FROM Accounts WHERE username = $2) as sender_id,
|
||||
(SELECT user_id FROM Accounts WHERE username = $3) as receiver_id
|
||||
(SELECT user_id FROM Accounts WHERE username = $2) as user_id,
|
||||
(SELECT user_id FROM Accounts WHERE username = $3) as contact_user_id
|
||||
)
|
||||
UPDATE Contacts SET read = $1
|
||||
WHERE sender_id = (SELECT sender_id FROM users)
|
||||
AND receiver_id = (SELECT receiver_id FROM users);
|
||||
WHERE user_id = (SELECT user_id FROM users)
|
||||
AND contact_user_id = (SELECT contact_user_id FROM users);
|
||||
`;
|
||||
try {
|
||||
await client.query(query, [read, user_id, receiver_id]);
|
||||
await updateContactLastActive(user_id, receiver_id);
|
||||
await client.query(query, [read, userUsername, contact_user_id]);
|
||||
await updateContactLastActive(userUsername, contact_user_id);
|
||||
console.log("Successfully updated contact status");
|
||||
} catch (e) {
|
||||
console.error("Failed to update contact status ", e);
|
||||
}
|
||||
}
|
||||
|
||||
async function updateContactLastActive(user_id, receiver_id) {
|
||||
async function updateContactLastActive(userUsername, receiverUsername) {
|
||||
const timestamp = getTime();
|
||||
const query = `
|
||||
UPDATE Contacts
|
||||
SET last_active = $1
|
||||
WHERE sender_id = (SELECT user_id FROM Accounts WHERE username = $2)
|
||||
AND receiver_id = (SELECT user_id FROM Accounts WHERE username = $3);
|
||||
WHERE user_id = (SELECT user_id FROM Accounts WHERE username = $2)
|
||||
AND contact_user_id = (SELECT user_id FROM Accounts WHERE username = $3);
|
||||
`;
|
||||
try {
|
||||
await client.query(query, [timestamp, user_id, receiver_id]);
|
||||
await client.query(query, [timestamp, userUsername, receiverUsername]);
|
||||
console.log("Successfully updated contact last active time");
|
||||
} catch (e) {
|
||||
console.error("Failed to update contact last active time ", e);
|
||||
|
||||
@@ -75,6 +75,7 @@ app.use(bodyParser.json());
|
||||
app.use(cookieParser());
|
||||
app.use(express.json({ limit: "100G" }));
|
||||
app.use(express.urlencoded({ extended: true, limit: "100G" }));
|
||||
|
||||
app.post("/api/auth/signup", async (req, res) => {
|
||||
try {
|
||||
const username = req.body.username;
|
||||
@@ -192,7 +193,7 @@ app.post("/api/auth/login", async (req, res) => {
|
||||
app.get("/api/auth/validate", authorizeUser, (req, res) => {
|
||||
return res.status(200).json({
|
||||
message: "Authorized",
|
||||
username: req.user.user_id,
|
||||
username: req.user.username,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -241,7 +242,11 @@ app.post("/api/chat/contact/:contact", authorizeUser, async (req, res) => {
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await insertContact(req.user.user_id, usernameContact, true);
|
||||
const result = await insertContact(
|
||||
req.user.username,
|
||||
usernameContact,
|
||||
true,
|
||||
);
|
||||
return res.status(200).json(result);
|
||||
} catch (e) {
|
||||
console.error("Failed to insert contact: ", e);
|
||||
@@ -273,6 +278,7 @@ app.get("/api/chat/messages/:contact", authorizeUser, async (req, res) => {
|
||||
// console.log("abcdefg", req.params.contact);
|
||||
// return res.status(400).json({ messaeg: "Invalid contact" });
|
||||
// }
|
||||
|
||||
const messages = await getMessages(
|
||||
req.user.user_id,
|
||||
contactId,
|
||||
|
||||
Reference in New Issue
Block a user