diff --git a/README.md b/README.md index 9962396..a671ea0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,12 @@ +[![Contributors][contributors-shield]][contributors-url] +[![Forks][forks-shield]][forks-url] +[![Stargazers][stars-shield]][stars-url] +[![Issues][issues-shield]][issues-url] +[![Apache 2.0 License][license-shield]][license-url] + # Android SMS Gateway Server -This server acts as the backend component of the Android SMS Gateway, facilitating the sending of SMS messages through connected Android devices. It includes a RESTful API for message management, integration with Firebase Cloud Messaging (FCM), and a database for persistent storage. +This server acts as the backend component of the [Android SMS Gateway](https://github.com/capcom6/android-sms-gateway), facilitating the sending of SMS messages through connected Android devices. It includes a RESTful API for message management, integration with Firebase Cloud Messaging (FCM), and a database for persistent storage. ## Table of Contents @@ -8,18 +14,17 @@ This server acts as the backend component of the Android SMS Gateway, facilitati - [Table of Contents](#table-of-contents) - [Features](#features) - [Prerequisites](#prerequisites) - - [Installation](#installation) - - [Configuration](#configuration) - - [Running the Server](#running-the-server) - - [Running with Docker](#running-with-docker) + - [Quickstart](#quickstart) + - [Work modes](#work-modes) - [Contributing](#contributing) - [License](#license) ## Features - Send SMS messages via a RESTful API. -- Schedule and perform periodic tasks. -- Integrate with Firebase Cloud Messaging for notifications. +- Get message status. +- Get the list of connected devices. +- Public and private modes. ## Prerequisites @@ -27,63 +32,30 @@ This server acts as the backend component of the Android SMS Gateway, facilitati - Docker and Docker Compose (for Docker-based setup) - A configured MySQL/MariaDB database -## Installation +## Quickstart -To set up the server on your local machine for development and testing purposes, follow these steps: +The easiest way to get started with the server is to use the Docker-based setup in Private Mode. In this mode device registration endpoint is protected, so no one can register a new device without knowing the token. -1. Clone the repository to your local machine. -2. Install Go (version 1.21 or newer) if not already installed. -3. Navigate to the cloned directory and install dependencies: +1. Set up MySQL or MariaDB database. +2. Create config.yml, based on [config.example.yml](configs/config.example.yml). The most important sections are `database`, `http` and `gateway`. Environment variables can be used to override values in the config file. + 1. In `gateway.mode` section set `private`. + 2. In `gateway.private_token` section set the access token for device registration in private mode. This token must be set on devices with private mode active. +3. Start the server in Docker: `docker run -p 3000:3000 -v ./config.yml:/app/config.yml capcom6/sms-gateway:latest`. +4. Set up private mode on devices. +5. Use started private server with the same API as the public server at [sms.capcom.me](https://sms.capcom.me). -```bash -make init -``` +See also [docker-composee.yml](deployments/docker-compose/docker-compose.yml) for Docker-based setup. -4. Build the server binary: +## Work modes -```bash -make build -``` +The server has two work modes: public and private. The public mode allows anonymous device registration and used at [sms.capcom.me](https://sms.capcom.me). Private mode can be used to send sensitive messages and running server in local infrastructure. -## Configuration +In most operations public and private modes are the same. But there are some differences: -The server uses `yaml` for configuration with ability to override some values from environment variables. By default configuration is loaded from the `config.yml` file in the root directory. But path can be overridden with the `CONFIG_PATH` environment variable. +- `POST /api/mobile/v1/device` endpoint is protected by API key in private mode. So it is not possible to register a new device on private server without knowing the token. +- FCM notifications from private server are sent through `sms.capcom.me`. Notifications don't contain any sensitive data like phone numbers or message text. -Below is a template for the `config.yml` file with environment variables in comments: - -```yaml -http: - listen: ":3000" # HTTP__LISTEN -database: - dialect: "mysql" # DATABASE__DIALECT - host: "localhost" # DATABASE__HOST - port: 3306 # DATABASE__PORT - user: "sms" # DATABASE__USER - password: "sms" # DATABASE__PASSWORD - database: "sms" # DATABASE__DATABASE - timezone: "UTC" # DATABASE__TIMEZONE -fcm: - credentials_json: > - { - ... - } -tasks: - hashing: - interval_seconds: 900 -``` - -Replace the placeholder values with your actual configuration. - -## Running the Server - -### Running with Docker - -For convenience, a Docker-based setup is provided. Please refer to the Docker prerequisites above before proceeding. - -1. Prepare configuration file `config.yml` -2. Pull the Docker image: `docker pull capcom6/sms-gateway` -3. Apply database migrations: `docker run --rm -it -v ./config.yml:/app/config.yml capcom6/sms-gateway db:migrate` -4. Start the server: `docker run -p 3000:3000 -v ./config.yml:/app/config.yml capcom6/sms-gateway` +See also [private mode discussion](https://github.com/capcom6/android-sms-gateway/issues/20). ## Contributing @@ -100,4 +72,15 @@ Don't forget to give the project a star! Thanks again! ## License -Distributed under the Apache-2.0 license. See [LICENSE](LICENSE) for more information. \ No newline at end of file +Distributed under the Apache-2.0 license. See [LICENSE](LICENSE) for more information. + +[contributors-shield]: https://img.shields.io/github/contributors/capcom6/sms-gateway.svg?style=for-the-badge +[contributors-url]: https://github.com/capcom6/sms-gateway/graphs/contributors +[forks-shield]: https://img.shields.io/github/forks/capcom6/sms-gateway.svg?style=for-the-badge +[forks-url]: https://github.com/capcom6/sms-gateway/network/members +[stars-shield]: https://img.shields.io/github/stars/capcom6/sms-gateway.svg?style=for-the-badge +[stars-url]: https://github.com/capcom6/sms-gateway/stargazers +[issues-shield]: https://img.shields.io/github/issues/capcom6/sms-gateway.svg?style=for-the-badge +[issues-url]: https://github.com/capcom6/sms-gateway/issues +[license-shield]: https://img.shields.io/github/license/capcom6/sms-gateway.svg?style=for-the-badge +[license-url]: https://github.com/capcom6/sms-gateway/blob/master/LICENSE \ No newline at end of file diff --git a/bitbucket-pipelines.yml b/bitbucket-pipelines.yml deleted file mode 100644 index 1e3882f..0000000 --- a/bitbucket-pipelines.yml +++ /dev/null @@ -1,81 +0,0 @@ -image: atlassian/default-image:3 - -definitions: - caches: - gomodules: ~/.cache/go-build - steps: - - step: &docker-lint - runs-on: - - self.hosted - - linux - name: Lint the Dockerfile - image: hadolint/hadolint:latest-debian - script: - - hadolint build/package/Dockerfile* - - step: &unit-tests - runs-on: - - self.hosted - - linux - name: Run unit tests - image: golang:1.20 - caches: - - gomodules - script: - - echo '[url "ssh://git@bitbucket.org/"]' >> ~/.gitconfig - - echo ' insteadOf = https://bitbucket.org/' >> ~/.gitconfig - - go env -w GOPRIVATE="bitbucket.org/soft-c/*" - - go test ./... - - step: &build-docker - runs-on: - - self.hosted - - linux - name: Build and push Docker image - services: - - docker - caches: - - docker - script: - - docker version - - echo ${DOCKER_PASSWORD} | docker login ${DOCKER_CR} --username "$DOCKER_USERNAME" --password-stdin - - export SSH_PRV_KEY="$(cat /opt/atlassian/pipelines/agent/ssh/id_rsa)" - - chmod +x ./scripts/docker-build.sh && ./scripts/docker-build.sh - - step: &deploy - runs-on: - - self.hosted - - linux - name: Deploy to Docker Swarm - image: hashicorp/terraform:1.4 - deployment: production - script: - - terraform -chdir=./deployments/docker-swarm-terraform init - - | - terraform -chdir=./deployments/docker-swarm-terraform apply -auto-approve -input=false \ - -var "swarm-manager-host=${SWARM_MANAGER_HOST}" \ - -var "registry-password=${DOCKER_PASSWORD}" \ - -var "app-name=${APP_NAME}" \ - -var "app-version=${BITBUCKET_TAG#v}" \ - -var "app-host=${APP_HOST}" \ - -var "app-config-b64=${APP_CONFIG_B64}" \ - -var "app-env-json-b64=${APP_ENV_JSON_B64}" - -pipelines: - default: - - parallel: - - step: *docker-lint - - step: *unit-tests - - step: *build-docker - branches: - testing: - - parallel: - - step: *docker-lint - - step: *unit-tests - - step: *build-docker - master: - - parallel: - - step: *docker-lint - - step: *unit-tests - - step: *build-docker - tags: - v*: - - step: *build-docker - - step: *deploy diff --git a/configs/config.example.yml b/configs/config.example.yml index 79fad75..6a61a37 100644 --- a/configs/config.example.yml +++ b/configs/config.example.yml @@ -1,24 +1,20 @@ -gateway: - mode: private - private_token: 123456789 +gateway: # gateway config [GATEWAY__MODE] + mode: private # gateway mode (public - allow anonymous device registration, private - protected registration) [GATEWAY__PRIVATE_TOKEN] + private_token: 123456789 # access token for device registration in private mode http: # http server config - listen: 127.0.0.1:3000 # listen address + listen: 127.0.0.1:3000 # listen address [HTTP__LISTEN] database: # database - dialect: mysql # database dialect - host: localhost # database host - port: 3306 # database port - user: root # database user - password: root # database password - database: sms # database name - debug: true - timezone: UTC -fcm: - credentials_json: > - { - ... - } - timeout_seconds: 1 - debounce_seconds: 1 -tasks: - hashing: - interval_seconds: 15 + dialect: mysql # database dialect (only mysql supported at the moment) [DATABASE__DIALECT] + host: localhost # database host [DATABASE__HOST] + port: 3306 # database port [DATABASE__PORT] + user: root # database user [DATABASE__USER] + password: root # database password [DATABASE__PASSWORD] + database: sms # database name [DATABASE__DATABASE] + timezone: UTC # database timezone (important for message TTL calculation) [DATABASE__TIMEZONE] +fcm: # firebase cloud messaging config + credentials_json: "{}" # firebase credentials json (for public mode only) [FCM__CREDENTIALS_JSON] + timeout_seconds: 1 # push notification send timeout [FCM__DEBOUNCE_SECONDS] + debounce_seconds: 5 # push notification debounce (>= 5s) [FCM__TIMEOUT_SECONDS] +tasks: # tasks config + hashing: # hashing task (hashes processed messages for privacy purposes) + interval_seconds: 15 # hashing interval in seconds [TASKS__HASHING__INTERVAL_SECONDS] diff --git a/deployments/docker-swarm-terraform/providers.tf b/deployments/docker-swarm-terraform/providers.tf index b781059..114f5de 100644 --- a/deployments/docker-swarm-terraform/providers.tf +++ b/deployments/docker-swarm-terraform/providers.tf @@ -10,9 +10,4 @@ terraform { provider "docker" { host = var.swarm-manager-host ssh_opts = ["-o", "StrictHostKeyChecking=no", "-o", "UserKnownHostsFile=/dev/null"] - # registry_auth { - # address = "cr.selcloud.ru/soft-c" - # username = "token" - # password = var.registry-password - # } } diff --git a/deployments/docker-swarm-terraform/variables.tf b/deployments/docker-swarm-terraform/variables.tf index 094ea21..6b95e98 100644 --- a/deployments/docker-swarm-terraform/variables.tf +++ b/deployments/docker-swarm-terraform/variables.tf @@ -4,12 +4,6 @@ variable "swarm-manager-host" { description = "Address of swarm manager" } -# variable "registry-password" { -# type = string -# description = "Password for Docker Images Registry" -# sensitive = true -# } - variable "app-name" { type = string description = "Name of app" diff --git a/internal/config/config.go b/internal/config/config.go index c3d36af..d3d2cba 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -8,11 +8,11 @@ const ( ) type Config struct { - Gateway Gateway `yaml:"gateway"` - HTTP HTTP `yaml:"http"` - Database Database `yaml:"database"` - FCM FCMConfig `yaml:"fcm"` - Tasks Tasks `yaml:"tasks"` + Gateway Gateway `yaml:"gateway"` // gateway config + HTTP HTTP `yaml:"http"` // http server config + Database Database `yaml:"database"` // database config + FCM FCMConfig `yaml:"fcm"` // firebase cloud messaging config + Tasks Tasks `yaml:"tasks"` // tasks config } type Gateway struct { @@ -21,23 +21,23 @@ type Gateway struct { } type HTTP struct { - Listen string `yaml:"listen" envconfig:"HTTP__LISTEN"` + Listen string `yaml:"listen" envconfig:"HTTP__LISTEN"` // listen address } type Database struct { - Dialect string `yaml:"dialect" envconfig:"DATABASE__DIALECT"` - Host string `yaml:"host" envconfig:"DATABASE__HOST"` - Port int `yaml:"port" envconfig:"DATABASE__PORT"` - User string `yaml:"user" envconfig:"DATABASE__USER"` - Password string `yaml:"password" envconfig:"DATABASE__PASSWORD"` - Database string `yaml:"database" envconfig:"DATABASE__DATABASE"` - Timezone string `yaml:"timezone" envconfig:"DATABASE__TIMEZONE"` + Dialect string `yaml:"dialect" envconfig:"DATABASE__DIALECT"` // database dialect + Host string `yaml:"host" envconfig:"DATABASE__HOST"` // database host + Port int `yaml:"port" envconfig:"DATABASE__PORT"` // database port + User string `yaml:"user" envconfig:"DATABASE__USER"` // database user + Password string `yaml:"password" envconfig:"DATABASE__PASSWORD"` // database password + Database string `yaml:"database" envconfig:"DATABASE__DATABASE"` // database name + Timezone string `yaml:"timezone" envconfig:"DATABASE__TIMEZONE"` // database timezone } type FCMConfig struct { - CredentialsJSON string `yaml:"credentials_json"` - DebounceSeconds uint16 `yaml:"debounce_seconds"` - TimeoutSeconds uint16 `yaml:"timeout_seconds"` + CredentialsJSON string `yaml:"credentials_json" envconfig:"FCM__CREDENTIALS_JSON"` // firebase credentials json (public mode only) + DebounceSeconds uint16 `yaml:"debounce_seconds" envconfig:"FCM__DEBOUNCE_SECONDS"` // push notification debounce (>= 5s) + TimeoutSeconds uint16 `yaml:"timeout_seconds" envconfig:"FCM__TIMEOUT_SECONDS"` // push notification send timeout } type Tasks struct { @@ -45,7 +45,7 @@ type Tasks struct { } type HashingTask struct { - IntervalSeconds uint16 `yaml:"interval_seconds"` + IntervalSeconds uint16 `yaml:"interval_seconds" envconfig:"TASKS__HASHING__INTERVAL_SECONDS"` // hashing interval in seconds } var defaultConfig = Config{ diff --git a/web/mkdocs/docs/getting-started.md b/web/mkdocs/docs/getting-started.md deleted file mode 100644 index b370748..0000000 --- a/web/mkdocs/docs/getting-started.md +++ /dev/null @@ -1,41 +0,0 @@ -# Getting Started - -First of all, you need to install the Android SMS Gateway app on your device as described in the [Installation](installation.md). - -The Android SMS Gateway can work in two modes: with a local server started on the device or with a cloud server at [sms.capcom.me](https://sms.capcom.me). The basic API is the same for both modes and is documented on the [Android SMS Gateway API Documentation](https://capcom6.github.io/android-sms-gateway/). - -## Local server - -
-
-
+
+
+