diff --git a/SHiNE-server/shine-server-db/src/main/java/shine/db/dao/DirectMessagesDAO.java b/SHiNE-server/shine-server-db/src/main/java/shine/db/dao/DirectMessagesDAO.java deleted file mode 100644 index ae063da4..00000000 --- a/SHiNE-server/shine-server-db/src/main/java/shine/db/dao/DirectMessagesDAO.java +++ /dev/null @@ -1,53 +0,0 @@ -package shine.db.dao; - -import shine.db.DbController; -import shine.db.entities.DirectMessageEntry; - -import java.sql.Connection; -import java.sql.PreparedStatement; - -public final class DirectMessagesDAO { - private static volatile DirectMessagesDAO instance; - private final DbController db = DbController.getInstance(); - - private DirectMessagesDAO() {} - - public static DirectMessagesDAO getInstance() { - if (instance == null) { - synchronized (DirectMessagesDAO.class) { - if (instance == null) instance = new DirectMessagesDAO(); - } - } - return instance; - } - - public void insert(DirectMessageEntry entry) throws Exception { - try (Connection c = db.getConnection()) { - String sql = """ - INSERT INTO direct_messages ( - message_id, from_login, to_login, text, created_at_ms - ) VALUES (?, ?, ?, ?, ?) - """; - try (PreparedStatement ps = c.prepareStatement(sql)) { - ps.setString(1, entry.getMessageId()); - ps.setString(2, entry.getFromLogin()); - ps.setString(3, entry.getToLogin()); - ps.setString(4, entry.getText()); - ps.setLong(5, entry.getCreatedAtMs()); - ps.executeUpdate(); - } - } - } - - public boolean existsFromTo(String fromLogin, String toLogin) throws Exception { - try (Connection c = db.getConnection()) { - String sql = "SELECT 1 FROM direct_messages WHERE from_login = ? AND to_login = ? LIMIT 1"; - try (PreparedStatement ps = c.prepareStatement(sql)) { - ps.setString(1, fromLogin); - ps.setString(2, toLogin); - return ps.executeQuery().next(); - } - } - } - -} diff --git a/SHiNE-server/shine-server-db/src/main/java/shine/db/dao/SignedDirectMessagesHistoryDAO.java b/SHiNE-server/shine-server-db/src/main/java/shine/db/dao/SignedDirectMessagesHistoryDAO.java deleted file mode 100644 index 0c9f9064..00000000 --- a/SHiNE-server/shine-server-db/src/main/java/shine/db/dao/SignedDirectMessagesHistoryDAO.java +++ /dev/null @@ -1,47 +0,0 @@ -package shine.db.dao; - -import shine.db.DbController; -import shine.db.entities.SignedDirectMessageHistoryEntry; - -import java.sql.Connection; -import java.sql.PreparedStatement; - -public final class SignedDirectMessagesHistoryDAO { - private static volatile SignedDirectMessagesHistoryDAO instance; - private final DbController db = DbController.getInstance(); - - private SignedDirectMessagesHistoryDAO() {} - - public static SignedDirectMessagesHistoryDAO getInstance() { - if (instance == null) { - synchronized (SignedDirectMessagesHistoryDAO.class) { - if (instance == null) instance = new SignedDirectMessagesHistoryDAO(); - } - } - return instance; - } - - public void insert(SignedDirectMessageHistoryEntry e) throws Exception { - try (Connection c = db.getConnection()) { - String sql = """ - INSERT INTO signed_direct_messages_history ( - message_id, from_login, to_login, target_mode, target_session_id, - message_type, time_ms, nonce, raw_packet, created_at_ms - ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) - """; - try (PreparedStatement ps = c.prepareStatement(sql)) { - ps.setString(1, e.getMessageId()); - ps.setString(2, e.getFromLogin()); - ps.setString(3, e.getToLogin()); - ps.setInt(4, e.getTargetMode()); - ps.setString(5, e.getTargetSessionId()); - ps.setInt(6, e.getMessageType()); - ps.setLong(7, e.getTimeMs()); - ps.setLong(8, e.getNonce()); - ps.setBytes(9, e.getRawPacket()); - ps.setLong(10, e.getCreatedAtMs()); - ps.executeUpdate(); - } - } - } -} diff --git a/SHiNE-server/shine-server-db/src/main/java/shine/db/dao/SignedDmReplayDAO.java b/SHiNE-server/shine-server-db/src/main/java/shine/db/dao/SignedDmReplayDAO.java deleted file mode 100644 index 9d11354b..00000000 --- a/SHiNE-server/shine-server-db/src/main/java/shine/db/dao/SignedDmReplayDAO.java +++ /dev/null @@ -1,51 +0,0 @@ -package shine.db.dao; - -import shine.db.DbController; - -import java.sql.Connection; -import java.sql.PreparedStatement; - -public final class SignedDmReplayDAO { - private static volatile SignedDmReplayDAO instance; - private final DbController db = DbController.getInstance(); - - private SignedDmReplayDAO() {} - - public static SignedDmReplayDAO getInstance() { - if (instance == null) { - synchronized (SignedDmReplayDAO.class) { - if (instance == null) instance = new SignedDmReplayDAO(); - } - } - return instance; - } - - public boolean registerUnique(String fromLogin, long timeMs, long nonce, long nowMs) throws Exception { - cleanupExpired(nowMs - 15L * 60L * 1000L); - try (Connection c = db.getConnection()) { - String sql = """ - INSERT INTO signed_direct_message_replay ( - from_login, time_ms, nonce, created_at_ms - ) VALUES (?, ?, ?, ?) - ON CONFLICT DO NOTHING - """; - try (PreparedStatement ps = c.prepareStatement(sql)) { - ps.setString(1, fromLogin); - ps.setLong(2, timeMs); - ps.setLong(3, nonce); - ps.setLong(4, nowMs); - return ps.executeUpdate() > 0; - } - } - } - - public void cleanupExpired(long minCreatedAtMs) throws Exception { - try (Connection c = db.getConnection()) { - String sql = "DELETE FROM signed_direct_message_replay WHERE created_at_ms < ?"; - try (PreparedStatement ps = c.prepareStatement(sql)) { - ps.setLong(1, minCreatedAtMs); - ps.executeUpdate(); - } - } - } -} diff --git a/SHiNE-server/shine-server-db/src/main/java/shine/db/entities/DirectMessageEntry.java b/SHiNE-server/shine-server-db/src/main/java/shine/db/entities/DirectMessageEntry.java deleted file mode 100644 index d916e6f6..00000000 --- a/SHiNE-server/shine-server-db/src/main/java/shine/db/entities/DirectMessageEntry.java +++ /dev/null @@ -1,24 +0,0 @@ -package shine.db.entities; - -public class DirectMessageEntry { - private String messageId; - private String fromLogin; - private String toLogin; - private String text; - private long createdAtMs; - - public String getMessageId() { return messageId; } - public void setMessageId(String messageId) { this.messageId = messageId; } - - public String getFromLogin() { return fromLogin; } - public void setFromLogin(String fromLogin) { this.fromLogin = fromLogin; } - - public String getToLogin() { return toLogin; } - public void setToLogin(String toLogin) { this.toLogin = toLogin; } - - public String getText() { return text; } - public void setText(String text) { this.text = text; } - - public long getCreatedAtMs() { return createdAtMs; } - public void setCreatedAtMs(long createdAtMs) { this.createdAtMs = createdAtMs; } -} diff --git a/SHiNE-server/shine-server-db/src/main/java/shine/db/entities/SignedDirectMessageHistoryEntry.java b/SHiNE-server/shine-server-db/src/main/java/shine/db/entities/SignedDirectMessageHistoryEntry.java deleted file mode 100644 index ca069f9b..00000000 --- a/SHiNE-server/shine-server-db/src/main/java/shine/db/entities/SignedDirectMessageHistoryEntry.java +++ /dev/null @@ -1,35 +0,0 @@ -package shine.db.entities; - -public class SignedDirectMessageHistoryEntry { - private String messageId; - private String fromLogin; - private String toLogin; - private int targetMode; - private String targetSessionId; - private int messageType; - private long timeMs; - private long nonce; - private byte[] rawPacket; - private long createdAtMs; - - public String getMessageId() { return messageId; } - public void setMessageId(String messageId) { this.messageId = messageId; } - public String getFromLogin() { return fromLogin; } - public void setFromLogin(String fromLogin) { this.fromLogin = fromLogin; } - public String getToLogin() { return toLogin; } - public void setToLogin(String toLogin) { this.toLogin = toLogin; } - public int getTargetMode() { return targetMode; } - public void setTargetMode(int targetMode) { this.targetMode = targetMode; } - public String getTargetSessionId() { return targetSessionId; } - public void setTargetSessionId(String targetSessionId) { this.targetSessionId = targetSessionId; } - public int getMessageType() { return messageType; } - public void setMessageType(int messageType) { this.messageType = messageType; } - public long getTimeMs() { return timeMs; } - public void setTimeMs(long timeMs) { this.timeMs = timeMs; } - public long getNonce() { return nonce; } - public void setNonce(long nonce) { this.nonce = nonce; } - public byte[] getRawPacket() { return rawPacket; } - public void setRawPacket(byte[] rawPacket) { this.rawPacket = rawPacket; } - public long getCreatedAtMs() { return createdAtMs; } - public void setCreatedAtMs(long createdAtMs) { this.createdAtMs = createdAtMs; } -} diff --git a/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/JsonHandlerRegistry.java b/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/JsonHandlerRegistry.java index 65719bf4..18bea259 100644 --- a/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/JsonHandlerRegistry.java +++ b/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/JsonHandlerRegistry.java @@ -94,7 +94,6 @@ import server.logic.ws_protocol.JSON.messages.Net_DmSyncBatch_Handler; import server.logic.ws_protocol.JSON.messages.Net_GetDirectMessages_Handler; import server.logic.ws_protocol.JSON.messages.Net_SendSignal_Handler; import server.logic.ws_protocol.JSON.messages.Net_ReceiveIncomingMessage_Handler; -import server.logic.ws_protocol.JSON.messages.Net_SendDirectMessage_Handler; import server.logic.ws_protocol.JSON.messages.Net_SendMessagePair_Handler; import server.logic.ws_protocol.JSON.messages.Net_SendTestWebPush_Handler; import server.logic.ws_protocol.JSON.messages.Net_UpsertPushToken_Handler; @@ -107,7 +106,6 @@ import server.logic.ws_protocol.JSON.messages.entyties.Net_DmSyncBatch_Request; import server.logic.ws_protocol.JSON.messages.entyties.Net_GetDirectMessages_Request; import server.logic.ws_protocol.JSON.messages.entyties.Net_SendSignal_Request; import server.logic.ws_protocol.JSON.messages.entyties.Net_ReceiveIncomingMessage_Request; -import server.logic.ws_protocol.JSON.messages.entyties.Net_SendDirectMessage_Request; import server.logic.ws_protocol.JSON.messages.entyties.Net_SendMessagePair_Request; import server.logic.ws_protocol.JSON.messages.entyties.Net_SendTestWebPush_Request; import server.logic.ws_protocol.JSON.messages.entyties.Net_UpsertPushToken_Request; diff --git a/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/messages/Net_SendDirectMessage_Handler.java b/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/messages/Net_SendDirectMessage_Handler.java deleted file mode 100644 index 32b80d64..00000000 --- a/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/messages/Net_SendDirectMessage_Handler.java +++ /dev/null @@ -1,208 +0,0 @@ -package server.logic.ws_protocol.JSON.messages; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; -import server.logic.ws_protocol.JSON.ActiveConnectionsRegistry; -import server.logic.ws_protocol.JSON.ConnectionContext; -import server.logic.ws_protocol.JSON.entyties.Net_Request; -import server.logic.ws_protocol.JSON.entyties.Net_Response; -import server.logic.ws_protocol.JSON.handlers.JsonMessageHandler; -import server.logic.ws_protocol.JSON.messages.entyties.Net_SendDirectMessage_Request; -import server.logic.ws_protocol.JSON.messages.entyties.Net_SendDirectMessage_Response; -import server.logic.ws_protocol.JSON.push.WebPushSender; -import server.logic.ws_protocol.JSON.push.WsEventSender; -import server.logic.ws_protocol.JSON.utils.NetExceptionResponseFactory; -import server.logic.ws_protocol.JSON.utils.NetIdGenerator; -import server.logic.ws_protocol.WireCodes; -import shine.db.dao.ActiveSessionsDAO; -import shine.db.dao.DirectMessagesDAO; -import shine.db.dao.SignedDirectMessagesHistoryDAO; -import shine.db.dao.SignedDmReplayDAO; -import shine.db.dao.CurrentUsersDAO; -import shine.db.entities.ActiveSessionEntry; -import shine.db.entities.DirectMessageEntry; -import shine.db.entities.SignedDirectMessageHistoryEntry; -import shine.db.entities.CurrentUserEntry; -import utils.crypto.Ed25519Util; - -import java.nio.charset.StandardCharsets; -import java.util.Base64; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.TimeUnit; - -public class Net_SendDirectMessage_Handler implements JsonMessageHandler { - private static final ObjectMapper MAPPER = new ObjectMapper(); - private static final long REPLAY_TTL_MS = 15L * 60L * 1000L; - private static final int MAX_MESSAGE_BYTES = 3000; - - @Override - public Net_Response handle(Net_Request baseRequest, ConnectionContext ctx) throws Exception { - Net_SendDirectMessage_Request req = (Net_SendDirectMessage_Request) baseRequest; - if (req.getBlobB64() == null || req.getBlobB64().isBlank()) { - return NetExceptionResponseFactory.error(req, WireCodes.Status.BAD_REQUEST, "BAD_FIELDS", "blobB64 обязателен"); - } - - final byte[] raw; - final SignedDirectMessagePacket packet; - try { - raw = Base64.getDecoder().decode(req.getBlobB64().trim()); - packet = SignedDirectMessagePacket.parse(raw, MAX_MESSAGE_BYTES); - } catch (IllegalArgumentException ex) { - return NetExceptionResponseFactory.error(req, WireCodes.Status.BAD_REQUEST, ex.getMessage(), "Некорректный формат пакета"); - } - - CurrentUserEntry fromUser = CurrentUsersDAO.getInstance().getByLogin(packet.fromLogin); - CurrentUserEntry toUser = CurrentUsersDAO.getInstance().getByLogin(packet.toLogin); - if (fromUser == null || toUser == null) { - return NetExceptionResponseFactory.error(req, 404, "USER_NOT_FOUND", "from/to пользователь не найден"); - } - - byte[] publicKey32; - try { - publicKey32 = Ed25519Util.keyFromBase64(fromUser.getClientKey()); - } catch (Exception e) { - return NetExceptionResponseFactory.error(req, WireCodes.Status.UNVERIFIED, "BAD_DEVICE_KEY", "Некорректный clientKey отправителя"); - } - if (!Ed25519Util.verify(packet.signedBody, packet.signature64, publicKey32)) { - return NetExceptionResponseFactory.error(req, WireCodes.Status.UNVERIFIED, "BAD_SIGNATURE", "Подпись не прошла проверку"); - } - - long now = System.currentTimeMillis(); - if (Math.abs(now - packet.timeMs) > REPLAY_TTL_MS) { - return NetExceptionResponseFactory.error(req, WireCodes.Status.UNVERIFIED, "BAD_TIME_WINDOW", "Время сообщения вышло за окно 15 минут"); - } - - boolean replayOk = SignedDmReplayDAO.getInstance().registerUnique(packet.fromLogin, packet.timeMs, packet.nonce, now); - if (!replayOk) { - return NetExceptionResponseFactory.error(req, WireCodes.Status.UNVERIFIED, "REPLAY", "Повторное сообщение заблокировано"); - } - - String messageId = NetIdGenerator.eventId("msg"); - String textForUi = new String(packet.messageBytes, StandardCharsets.UTF_8); - - DirectMessageEntry entry = new DirectMessageEntry(); - entry.setMessageId(messageId); - entry.setFromLogin(packet.fromLogin); - entry.setToLogin(packet.toLogin); - entry.setText(textForUi); - entry.setCreatedAtMs(now); - DirectMessagesDAO.getInstance().insert(entry); - - SignedDirectMessageHistoryEntry history = new SignedDirectMessageHistoryEntry(); - history.setMessageId(messageId); - history.setFromLogin(packet.fromLogin); - history.setToLogin(packet.toLogin); - history.setTargetMode(packet.targetMode); - history.setTargetSessionId(packet.targetSessionId); - history.setMessageType(packet.messageType); - history.setTimeMs(packet.timeMs); - history.setNonce(packet.nonce); - history.setRawPacket(packet.rawPacket); - history.setCreatedAtMs(now); - SignedDirectMessagesHistoryDAO.getInstance().insert(history); - - DeliveryResult delivery = deliver(packet, req.getBlobB64().trim(), messageId, now); - - Net_SendDirectMessage_Response resp = new Net_SendDirectMessage_Response(); - resp.setOp(req.getOp()); - resp.setRequestId(req.getRequestId()); - resp.setStatus(WireCodes.Status.OK); - resp.setMessageId(messageId); - resp.setDeliveredWsSessions(delivery.wsDelivered); - resp.setDeliveredWebPushSessions(delivery.webPushDelivered); - resp.setSessionNotFound(delivery.sessionNotFound); - return resp; - } - - private DeliveryResult deliver(SignedDirectMessagePacket packet, String blobB64, String messageId, long createdAtMs) throws Exception { - DeliveryResult result = new DeliveryResult(); - - Set selectedSessionIds = new HashSet<>(); - if (packet.targetMode == SignedDirectMessagePacket.TARGET_ONE_SESSION) { - ActiveSessionEntry byId = ActiveSessionsDAO.getInstance().getBySessionId(packet.targetSessionId); - if (byId == null || !packet.toLogin.equalsIgnoreCase(byId.getLogin())) { - result.sessionNotFound = true; - return result; - } - selectedSessionIds.add(byId.getSessionId()); - deliverToSession(packet, blobB64, messageId, createdAtMs, byId.getSessionId(), result); - return result; - } - - List sessions = ActiveSessionsDAO.getInstance().getByLogin(packet.toLogin); - for (ActiveSessionEntry s : sessions) { - selectedSessionIds.add(s.getSessionId()); - deliverToSession(packet, blobB64, messageId, createdAtMs, s.getSessionId(), result); - } - return result; - } - - private void deliverToSession( - SignedDirectMessagePacket packet, - String blobB64, - String messageId, - long createdAtMs, - String sessionId, - DeliveryResult result - ) { - ConnectionContext targetCtx = ActiveConnectionsRegistry.getInstance().getBySessionId(sessionId); - boolean wsDelivered = false; - if (targetCtx != null) { - String eventId = NetIdGenerator.eventId("evt"); - CompletableFuture waiter = DeliveryTracker.getInstance().register(eventId); - ObjectNode payload = MAPPER.createObjectNode(); - payload.put("eventId", eventId); - payload.put("messageId", messageId); - payload.put("fromLogin", packet.fromLogin); - payload.put("toLogin", packet.toLogin); - payload.put("blobB64", blobB64); - payload.put("text", new String(packet.messageBytes, StandardCharsets.UTF_8)); - payload.put("timeMs", createdAtMs); - - boolean sent = WsEventSender.sendEvent(targetCtx, "IncomingDirectMessage", eventId, payload); - if (sent) { - try { - wsDelivered = waiter.get(1200, TimeUnit.MILLISECONDS); - } catch (Exception ignored) { - wsDelivered = false; - } - } - DeliveryTracker.getInstance().remove(eventId); - } - - if (wsDelivered) { - result.wsDelivered++; - return; - } - - try { - ActiveSessionEntry targetSession = ActiveSessionsDAO.getInstance().getBySessionId(sessionId); - if (targetSession == null) return; - if (isBlank(targetSession.getPushEndpoint()) || isBlank(targetSession.getPushP256dhKey()) || isBlank(targetSession.getPushAuthKey())) { - return; - } - boolean pushed = WebPushSender.sendBase64Payload( - targetSession.getPushEndpoint(), - targetSession.getPushP256dhKey(), - targetSession.getPushAuthKey(), - blobB64 - ); - if (pushed) result.webPushDelivered++; - } catch (Exception ignored) { - // ignore per-session push errors - } - } - - private boolean isBlank(String s) { - return s == null || s.isBlank(); - } - - private static final class DeliveryResult { - int wsDelivered; - int webPushDelivered; - boolean sessionNotFound; - } -} diff --git a/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/messages/entyties/Net_SendDirectMessage_Request.java b/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/messages/entyties/Net_SendDirectMessage_Request.java deleted file mode 100644 index cf52bc97..00000000 --- a/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/messages/entyties/Net_SendDirectMessage_Request.java +++ /dev/null @@ -1,10 +0,0 @@ -package server.logic.ws_protocol.JSON.messages.entyties; - -import server.logic.ws_protocol.JSON.entyties.Net_Request; - -public class Net_SendDirectMessage_Request extends Net_Request { - private String blobB64; - - public String getBlobB64() { return blobB64; } - public void setBlobB64(String blobB64) { this.blobB64 = blobB64; } -} diff --git a/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/messages/entyties/Net_SendDirectMessage_Response.java b/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/messages/entyties/Net_SendDirectMessage_Response.java deleted file mode 100644 index 88337375..00000000 --- a/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/messages/entyties/Net_SendDirectMessage_Response.java +++ /dev/null @@ -1,19 +0,0 @@ -package server.logic.ws_protocol.JSON.messages.entyties; - -import server.logic.ws_protocol.JSON.entyties.Net_Response; - -public class Net_SendDirectMessage_Response extends Net_Response { - private String messageId; - private int deliveredWsSessions; - private int deliveredWebPushSessions; - private boolean sessionNotFound; - - public String getMessageId() { return messageId; } - public void setMessageId(String messageId) { this.messageId = messageId; } - public int getDeliveredWsSessions() { return deliveredWsSessions; } - public void setDeliveredWsSessions(int deliveredWsSessions) { this.deliveredWsSessions = deliveredWsSessions; } - public int getDeliveredWebPushSessions() { return deliveredWebPushSessions; } - public void setDeliveredWebPushSessions(int deliveredWebPushSessions) { this.deliveredWebPushSessions = deliveredWebPushSessions; } - public boolean isSessionNotFound() { return sessionNotFound; } - public void setSessionNotFound(boolean sessionNotFound) { this.sessionNotFound = sessionNotFound; } -} diff --git a/VERSION.properties b/VERSION.properties index 1e462d05..c16c29a1 100644 --- a/VERSION.properties +++ b/VERSION.properties @@ -1,2 +1,2 @@ client.version=1.7.0 -server.version=1.6.0 +server.version=1.6.1 diff --git a/docs/API/09_Operations_Index.md b/docs/API/09_Operations_Index.md index 95826e81..e7d20fac 100644 --- a/docs/API/09_Operations_Index.md +++ b/docs/API/09_Operations_Index.md @@ -71,7 +71,6 @@ ## Важные замечания - `ReceiveOutcomingMessage` сейчас зарегистрирован как алиас того же handler/request-класса, что и `SendMessagePair`. -- Legacy-операция `SendDirectMessage` больше не зарегистрирована и не должна использоваться для DM v1. - Отдельных HTTP endpoints для DM-файлов сейчас нет. - Классы `Net_MarkChannelMessagesSeen_*` существуют в коде, но операция `MarkChannelMessagesSeen` не зарегистрирована в `JsonHandlerRegistry`, поэтому в публичный список API не входит. - HTTP debug endpoints из `src/main/java/server/debug/` не входят в этот индекс WebSocket `op`; они описаны отдельно в `13_HTTP_Debug_API.md`. diff --git a/docs/API/12_Direct_Messages_Push_Calls_API.md b/docs/API/12_Direct_Messages_Push_Calls_API.md index f576bb2e..6bd5d554 100644 --- a/docs/API/12_Direct_Messages_Push_Calls_API.md +++ b/docs/API/12_Direct_Messages_Push_Calls_API.md @@ -9,7 +9,6 @@ Важно: -- legacy-операция `SendDirectMessage` отключена и не зарегистрирована в публичном API; - для DM v1 нужно использовать `SendMessagePair`, `ReceiveOutcomingMessage`, `ReceiveIncomingMessage`, `DeleteMessage`, `DeleteConversation`, `GetDirectMessages`; - `DmSyncBatch` предназначен для межсерверной догоняющей синхронизации, не для обычного клиентского UI. diff --git a/docs/Personal_Messages/Протокол_DM_v1.md b/docs/Personal_Messages/Протокол_DM_v1.md index 50fa4ad8..b6843f3f 100644 --- a/docs/Personal_Messages/Протокол_DM_v1.md +++ b/docs/Personal_Messages/Протокол_DM_v1.md @@ -334,8 +334,6 @@ ### 8.2. Новые методы, которые нужны -Отдельный legacy-метод `SendDirectMessage` в DM v1 не используется и должен оставаться отключённым, чтобы не было параллельного старого стека доставки. - ## 9. Правила валидации и применения ### 9.1. Общее правило по ревизиям @@ -653,7 +651,6 @@ UI-следствие для клиента: - межсерверная маршрутизация DM должна идти через `access_servers`; - сервер должен добирать отсутствующих пользователей из Solana PDA до проверки подписи DM; - при выборе актуальной версии должен учитываться `reencryptedAtMs`, если `revisionTimeMs` совпадает; -- legacy `SendDirectMessage` должен быть отключён; - логика должна быть безопасна для нескольких серверов у каждой стороны. ## 14. Что в v1 пока не входит