feat: add plaintext admin message endpoint for testing
- New POST /api/admin/send-message endpoint (admin-only) - Messages prefixed with [PLAINTEXT] bypass E2EE decryption - App recognizes [PLAINTEXT] marker and strips it before display - Allows easy chat testing without E2EE key management
This commit is contained in:
parent
30e86bb7e0
commit
ca6cfbfad9
2 changed files with 64 additions and 5 deletions
|
|
@ -70,11 +70,20 @@ internal class MessageRepositoryImpl @Inject constructor(
|
|||
when (event) {
|
||||
is WebSocketEvent.NewMessage -> {
|
||||
val msg = event.message
|
||||
val decryptedBody = try {
|
||||
e2eeKeyManager.decryptMessage(msg.body)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "E2EE: Failed to decrypt message ${msg.id}", e)
|
||||
"[Entschlüsselung fehlgeschlagen]"
|
||||
val decryptedBody = when {
|
||||
msg.body.startsWith("[PLAINTEXT] ") -> {
|
||||
// Admin test messages – remove prefix
|
||||
msg.body.removePrefix("[PLAINTEXT] ")
|
||||
}
|
||||
else -> {
|
||||
// E2EE messages – decrypt
|
||||
try {
|
||||
e2eeKeyManager.decryptMessage(msg.body)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "E2EE: Failed to decrypt message ${msg.id}", e)
|
||||
"[Entschlüsselung fehlgeschlagen]"
|
||||
}
|
||||
}
|
||||
}
|
||||
dao.upsert(
|
||||
MessageEntity(
|
||||
|
|
|
|||
|
|
@ -95,4 +95,54 @@ internal fun Route.messageRoutes(
|
|||
call.respond(HttpStatusCode.OK, messages)
|
||||
}
|
||||
}
|
||||
|
||||
route("/api/admin/send-message") {
|
||||
post {
|
||||
val principal = call.principal<UserPrincipal>()
|
||||
?: return@post call.respond(
|
||||
HttpStatusCode.Unauthorized,
|
||||
ErrorResponse(status = 401, message = "Unauthorized")
|
||||
)
|
||||
// Only admins can send test messages
|
||||
if (!principal.isAdmin) {
|
||||
return@post call.respond(
|
||||
HttpStatusCode.Forbidden,
|
||||
ErrorResponse(status = 403, message = "Admin access required")
|
||||
)
|
||||
}
|
||||
|
||||
val request = call.receive<SendMessageRequest>()
|
||||
if (request.body.isBlank()) {
|
||||
call.respond(
|
||||
HttpStatusCode.BadRequest,
|
||||
ErrorResponse(status = 400, message = "Body must not be empty")
|
||||
)
|
||||
return@post
|
||||
}
|
||||
if (userRepository.findById(request.receiverId) == null) {
|
||||
call.respond(
|
||||
HttpStatusCode.NotFound,
|
||||
ErrorResponse(status = 404, message = "Receiver not found")
|
||||
)
|
||||
return@post
|
||||
}
|
||||
|
||||
val msgId = request.id ?: UUID.randomUUID().toString()
|
||||
// Wrap body with [PLAINTEXT] marker so app doesn't try to decrypt
|
||||
val plaintext = "[PLAINTEXT] ${request.body}"
|
||||
val message = messageRepository.save(
|
||||
id = msgId,
|
||||
senderId = principal.userId,
|
||||
senderUsername = principal.username,
|
||||
receiverId = request.receiverId,
|
||||
body = plaintext,
|
||||
sentAt = request.sentAt
|
||||
)
|
||||
wsManager.notifyNewMessage(request.receiverId, message)
|
||||
if (wsManager.isOnline(request.receiverId)) {
|
||||
messageRepository.markDelivered(msgId)
|
||||
}
|
||||
call.respond(HttpStatusCode.Created, SendMessageResponse(message = message))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue