· 4 months ago · May 21, 2025, 01:15 PM
1const knexConfig = require('../../../knexfile');
2const env = process.env.NODE_ENV || 'development';
3const knex = require('knex')(knexConfig[env]);
4
5/**
6 * Uwierzytelnia użytkownika na podstawie nazwy użytkownika i hasła.
7 * @param {string} username - Nazwa użytkownika.
8 * @param {string} password - Hasło użytkownika.
9 * @returns {Promise<number|null>} ID użytkownika (UserId) w przypadku pomyślnego uwierzytelnienia, w przeciwnym razie null.
10 */
11async function loginUser(username, password)
12{
13 if (!username || !password)
14 {
15 console.error('Błąd w loginUser: Nazwa użytkownika i hasło są wymagane.');
16 return null;
17 }
18
19 try
20 {
21 const user = await knex('User')
22 .where({ Username: username })
23 .first();
24
25 if (user)
26 {
27 const passwordMatch = (password === user.PasswordHash);
28 if (passwordMatch)
29 {
30 return user.UserId;
31 }
32 else
33 {
34 console.log(`Błąd w loginUser: Nieprawidłowe hasło dla użytkownika ${username}`);
35 return null;
36 }
37 }
38 else
39 {
40 console.log(`Błąd w loginUser: Użytkownik ${username} nie został znaleziony.`);
41 return null;
42 }
43 }
44 catch (error)
45 {
46 console.error('Błąd zapytania w loginUser:', error);
47 return null;
48 }
49}
50
51/**
52 * Tworzy nowego użytkownika w bazie danych.
53 * @param {string} username - Nazwa użytkownika.
54 * @param {string} password - Hasło użytkownika (czysty tekst).
55 * @param {string} email - Adres email użytkownika.
56 * @param {string} publicKey - Klucz publiczny użytkownika.
57 * @param {string} privateKey - Klucz prywatny użytkownika (zaszyfrowany).
58 * @returns {Promise<object>} Obiekt nowo utworzonego użytkownika.
59 */
60async function createUser(username, password, email, publicKey, privateKey)
61{
62 try
63 {
64 const passwordHash = password;
65 const [newUser] = await knex('User')
66 .insert({
67 Username: username,
68 UsernameShow: username,
69 PasswordHash: passwordHash,
70 Email: email,
71 PublicKey: publicKey,
72 PrivateKey: privateKey,
73 // UpdatedAt jest generowany automatycznie przez bazę danych
74 })
75 .returning(['UserId', 'Username', 'UsernameShow', 'Email', 'PublicKey', 'UpdatedAt']);
76
77 return newUser;
78 }
79 catch (error)
80 {
81 console.error('Błąd podczas tworzenia użytkownika:', error);
82
83 if (error.constraint === 'User_Username_key')
84 {
85 throw new Error('Nazwa użytkownika jest już zajęta.');
86 }
87 if (error.constraint === 'User_Email_key')
88 {
89 throw new Error('Adres email jest już używany.');
90 }
91 throw error;
92 }
93}
94
95/**
96 * Dodaje nową wiadomość do konwersacji.
97 * @param {string} conversationId - ID konwersacji.
98 * @param {string} userId - ID użytkownika wysyłającego wiadomość.
99 * @param {string} content - Treść wiadomości.
100 * @returns {Promise<object>} Obiekt nowo utworzonej wiadomości.
101 */
102async function addMessageToConversation(conversationId, userId, content)
103{
104 try
105 {
106 await knex.transaction(async trx =>
107 {
108 // Sprawdzenie, czy użytkownik należy do konwersacji
109 const participation = await trx('ConversationUser')
110 .where({
111 UserId: userId,
112 ConversationId: conversationId
113 })
114 .first();
115
116 if (!participation)
117 {
118 throw new Error('Użytkownik nie należy do tej konwersacji.');
119 } const [newMessage] = await trx('Message')
120 .insert({
121 UserId: userId,
122 ConversationId: conversationId,
123 Content: content,
124 // SendAt jest generowany automatycznie
125 })
126 .returning('*');
127 return newMessage;
128 });
129 }
130 catch (error)
131 {
132 console.error('Błąd podczas dodawania wiadomości do konwersacji:', error);
133 throw error;
134 }
135}
136
137/**
138 * Tworzy nową konwersację pomiędzy dwoma użytkownikami.
139 * @param {string} userId1 - ID użytkownika inicjującego konwersację.
140 * @param {string} userId2 - ID drugiego użytkownika.
141 * @param {string} encryptedConversationKeyUser1 - Zaszyfrowany klucz konwersacji dla użytkownika 1.
142 * @param {string} encryptedConversationKeyUser2 - Zaszyfrowany klucz konwersacji dla użytkownika 2.
143 * @returns {Promise<string|boolean>} ID nowej konwersacji w przypadku sukcesu, w przeciwnym razie false.
144 */
145async function createConversation(userId1, userId2, encryptedConversationKeyUser1, encryptedConversationKeyUser2)
146{
147 try
148 {
149 const isBlocked1 = await knex('BlockedUser')
150 .where({ UserId: userId1, BlockedUserId: userId2 })
151 .first();
152 const isBlocked2 = await knex('BlockedUser')
153 .where({ UserId: userId2, BlockedUserId: userId1 })
154 .first();
155
156 if (isBlocked1 || isBlocked2)
157 {
158 console.log('Nie można utworzyć konwersacji: jeden z użytkowników zablokował drugiego.');
159 return false;
160 }
161
162 const user2Details = await knex('User')
163 .where({ UserId: userId2 })
164 .select('UsernameShow')
165 .first();
166
167 if (!user2Details)
168 {
169 console.error('Błąd w createConversation: Nie znaleziono drugiego użytkownika.');
170 return false;
171 }
172
173 const conversationName = user2Details.UsernameShow;
174 let newConversationId;
175
176 await knex.transaction(async trx =>
177 {
178 const [newConversation] = await trx('Conversation')
179 .insert({
180 Name: conversationName,
181 })
182 .returning('ConversationId');
183
184 newConversationId = newConversation.ConversationId;
185
186 await trx('ConversationUser').insert([
187 {
188 UserId: userId1,
189 ConversationId: newConversationId,
190 EncryptedConversationKey: encryptedConversationKeyUser1,
191 },
192 {
193 UserId: userId2,
194 ConversationId: newConversationId,
195 EncryptedConversationKey: encryptedConversationKeyUser2,
196 }
197 ]);
198 });
199
200 return newConversationId;
201
202 }
203 catch (error)
204 {
205 console.error('Błąd podczas tworzenia konwersacji:', error);
206 return false;
207 }
208}
209
210
211module.exports =
212{
213 createUser,
214 addMessageToConversation,
215 loginUser,
216 createConversation
217};
218