Skip to content

Commit

Permalink
Merge pull request #41 from capcom6/issue/40-phone-number-validation
Browse files Browse the repository at this point in the history
Disable phone number validation by API option
  • Loading branch information
capcom6 authored Feb 13, 2024
2 parents fad7557 + 529d8e0 commit 32da2ef
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 58 deletions.
1 change: 1 addition & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ dependencies {
implementation("io.ktor:ktor-server-netty:$ktor_version")
implementation("io.ktor:ktor-server-cors:$ktor_version")
implementation("io.ktor:ktor-server-compression:$ktor_version")
implementation "io.ktor:ktor-server-status-pages:$ktor_version"

implementation("io.ktor:ktor-server-content-negotiation:$ktor_version")
implementation("io.ktor:ktor-serialization-gson:$ktor_version")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,8 @@ class GatewayModule(
),
SendParams(
message.withDeliveryReport ?: true,
message.simNumber
skipPhoneValidation = true,
simNumber = message.simNumber,
)
)
messagesService.enqueueMessage(request)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import io.ktor.server.engine.embeddedServer
import io.ktor.server.netty.Netty
import io.ktor.server.plugins.contentnegotiation.ContentNegotiation
import io.ktor.server.plugins.cors.routing.CORS
import io.ktor.server.plugins.statuspages.StatusPages
import io.ktor.server.request.receive
import io.ktor.server.response.respond
import io.ktor.server.routing.get
Expand Down Expand Up @@ -69,14 +70,25 @@ class WebService : Service() {
}
}
}
routing {
install(ContentNegotiation) {
gson {
if (me.capcom.smsgateway.BuildConfig.DEBUG) {
setPrettyPrinting()
}
install(ContentNegotiation) {
gson {
if (me.capcom.smsgateway.BuildConfig.DEBUG) {
setPrettyPrinting()
}
}
}
install(StatusPages) {
exception<Throwable> { call, cause ->
call.respond(
when (cause) {
is IllegalArgumentException -> HttpStatusCode.BadRequest
else -> HttpStatusCode.InternalServerError
},
mapOf("message" to cause.message)
)
}
}
routing {
install(CORS) {
anyHost()
allowHeader(HttpHeaders.ContentType)
Expand Down Expand Up @@ -109,35 +121,27 @@ class WebService : Service() {
mapOf("message" to "simNumber must be >= 1")
)
}
val skipPhoneValidation =
call.request.queryParameters["skipPhoneValidation"]
?.toBooleanStrict() ?: false

val messageId = try {
val sendRequest = SendRequest(
MessageSource.Local,
me.capcom.smsgateway.modules.messages.data.Message(
request.id ?: NanoIdUtils.randomNanoId(),
request.message,
request.phoneNumbers,
request.isEncrypted ?: false
),
me.capcom.smsgateway.modules.messages.data.SendParams(
request.withDeliveryReport ?: true,
request.simNumber
)
val sendRequest = SendRequest(
MessageSource.Local,
me.capcom.smsgateway.modules.messages.data.Message(
request.id ?: NanoIdUtils.randomNanoId(),
request.message,
request.phoneNumbers,
request.isEncrypted ?: false
),
me.capcom.smsgateway.modules.messages.data.SendParams(
request.withDeliveryReport ?: true,
skipPhoneValidation = skipPhoneValidation,
simNumber = request.simNumber,
)
messagesService.enqueueMessage(sendRequest)
)
messagesService.enqueueMessage(sendRequest)

sendRequest.message.id
} catch (e: IllegalArgumentException) {
return@post call.respond(
HttpStatusCode.BadRequest,
mapOf("message" to e.message)
)
} catch (e: Throwable) {
return@post call.respond(
HttpStatusCode.InternalServerError,
mapOf("message" to e.message)
)
}
val messageId = sendRequest.message.id

call.respond(
HttpStatusCode.Accepted,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,7 @@ class MessagesService(

try {
sendSMS(
message.message.id,
message.message.text,
message.recipients.filter { it.state == Message.State.Pending }
.map { it.phoneNumber },
request.params.simNumber?.let { it - 1 },
request.params.withDeliveryReport,
message.message.isEncrypted
request
)
} catch (e: Exception) {
e.printStackTrace()
Expand Down Expand Up @@ -181,22 +175,21 @@ class MessagesService(
}

private suspend fun sendSMS(
id: String,
message: String,
recipients: List<String>,
simNumber: Int?,
withDeliveryReport: Boolean,
isEncrypted: Boolean
request: SendRequest
) {
val smsManager: SmsManager = getSmsManager(simNumber)
val message = request.message
val params = request.params
val id = message.id

val smsManager: SmsManager = getSmsManager(params.simNumber?.let { it - 1 })

@Suppress("NAME_SHADOWING")
val message = when (isEncrypted) {
true -> encryptionService.decrypt(message)
false -> message
val messageText = when (message.isEncrypted) {
true -> encryptionService.decrypt(message.text)
false -> message.text
}

recipients.forEach {
message.phoneNumbers.forEach {
val sentIntent = PendingIntent.getBroadcast(
context,
0,
Expand All @@ -208,7 +201,7 @@ class MessagesService(
),
PendingIntent.FLAG_IMMUTABLE
)
val deliveredIntent = when (withDeliveryReport) {
val deliveredIntent = when (params.withDeliveryReport) {
false -> null
true -> PendingIntent.getBroadcast(
context,
Expand All @@ -224,13 +217,16 @@ class MessagesService(
}

try {
val parts = smsManager.divideMessage(message)
val phoneNumber = when (isEncrypted) {
val parts = smsManager.divideMessage(messageText)
val phoneNumber = when (message.isEncrypted) {
true -> encryptionService.decrypt(it)
false -> it
}
val normalizedPhoneNumber =
PhoneHelper.filterPhoneNumber(phoneNumber, countryCode ?: "RU")
val normalizedPhoneNumber = when (params.skipPhoneValidation) {
true -> phoneNumber.filter { it.isDigit() || it == '+' }
false -> PhoneHelper.filterPhoneNumber(phoneNumber, countryCode ?: "RU")
}

if (parts.size > 1) {
smsManager.sendMultipartTextMessage(
normalizedPhoneNumber,
Expand All @@ -243,7 +239,7 @@ class MessagesService(
smsManager.sendTextMessage(
normalizedPhoneNumber,
null,
message,
messageText,
sentIntent,
deliveredIntent
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,9 @@ package me.capcom.smsgateway.modules.messages.data

class SendParams(
val withDeliveryReport: Boolean,
val skipPhoneValidation: Boolean,
/**
* Sim number (from 1 to 3)
*/
val simNumber: Int? = null,
)
19 changes: 18 additions & 1 deletion docs/api/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,17 @@
"summary": "Send message",
"description": "Adds a message to the queue for sending",
"operationId": "post-message",
"parameters": [
{
"name": "skipPhoneValidation",
"in": "query",
"description": "if `true` phone numbers will be used as is",
"schema": {
"type": "boolean",
"default": false
}
}
],
"requestBody": {
"$ref": "#/components/requestBodies/SendMessageRequest"
},
Expand Down Expand Up @@ -202,10 +213,16 @@
"ttl": {
"type": "integer",
"nullable": true,
"description": "*(cloud-only)* message storage time in `Pending` state, `null` - forever",
"description": "expiration timeout, conflicts with `validUntil`",
"minimum": 5,
"example": 86400
},
"validUntil": {
"type": "string",
"nullable": true,
"description": "expiration date, conflicts with `ttl`",
"format": "date-time"
},
"withDeliveryReport": {
"type": "boolean",
"description": "request delivery report",
Expand Down

0 comments on commit 32da2ef

Please sign in to comment.