docs: test + deploy + environmental variables (#14)
* doc: test + deploy + environmental variables * doc: local dev and testing(WIP) * dev: set up local testing * fix: ci: add DATABASE_URL env * chore: update .env * ci: fix * dev: docker-compose-dev.yml * ci: update * ci: test env * ci: add services * ci: add services * ci: update port * ci: rename ci.yaml to rustlint.yaml * ci: test * ci: simplify tests * ci: use cargo sqlx commands directly * ci: fix: registered user * ci: fix: test registered user creation * ci: fix: test registered user creation - 2 * ci: fix: debug docker ci * ci: fix: docker integration registered user * ci: fix: docker integration registered user --------- Co-authored-by: nathan <nathan@appflowy.io>
This commit is contained in:
parent
e2e6d79cb0
commit
36499be26c
|
|
@ -1,38 +0,0 @@
|
||||||
name: AppFlowyCloud
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ main ]
|
|
||||||
pull_request:
|
|
||||||
types: [ opened, synchronize, reopened ]
|
|
||||||
branches: [ main ]
|
|
||||||
|
|
||||||
env:
|
|
||||||
SQLX_VERSION: 0.7.1
|
|
||||||
SQLX_FEATURES: "rustls,postgres"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
name: Unit Tests
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- uses: dtolnay/rust-toolchain@stable
|
|
||||||
- uses: Swatinem/rust-cache@v2
|
|
||||||
with:
|
|
||||||
workspaces: |
|
|
||||||
AppFlowy-Cloud
|
|
||||||
|
|
||||||
- name: Install Development Dependencies
|
|
||||||
run: |
|
|
||||||
cargo install sqlx-cli --version=${{ env.SQLX_VERSION }} --features ${{ env.SQLX_FEATURES }} --no-default-features --locked
|
|
||||||
sudo apt-get install libpq-dev -y
|
|
||||||
./build/init_database.sh
|
|
||||||
./build/init_redis.sh
|
|
||||||
|
|
||||||
- name: Check sqlx-data.json
|
|
||||||
run: |
|
|
||||||
cargo sqlx prepare --check -- --bin appflowy_cloud
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
name: AppFlowyCloud
|
name: AppFlowy-Cloud Integrations
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
|
@ -8,9 +8,10 @@ on:
|
||||||
branches: [ main ]
|
branches: [ main ]
|
||||||
|
|
||||||
env:
|
env:
|
||||||
APP__GOTRUE__BASE_URL: http://localhost:3000
|
GOTRUE_REGISTERED_EMAIL: zack@appflowy.io
|
||||||
APP__GOTRUE__JWT_SECRET: hello123
|
GOTRUE_REGISTERED_PASSWORD: Hello123!
|
||||||
GOTRUE_SMTP_PASS: ${{ secrets.GOTRUE_SMTP_PASS }}
|
SQLX_VERSION: 0.7.1
|
||||||
|
SQLX_FEATURES: "rustls,postgres"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
|
|
@ -25,20 +26,41 @@ jobs:
|
||||||
workspaces: |
|
workspaces: |
|
||||||
AppFlowy-Cloud
|
AppFlowy-Cloud
|
||||||
|
|
||||||
|
- name: Copy and rename dev.env to .env
|
||||||
|
run: cp dev.env .env
|
||||||
|
|
||||||
|
- name: Replace values in .env
|
||||||
|
run: |
|
||||||
|
sed -i 's/GOTRUE_SMTP_USER=.*/GOTRUE_SMTP_USER=${{ secrets.GOTRUE_SMTP_USER }}/' .env
|
||||||
|
sed -i 's/GOTRUE_SMTP_PASS=.*/GOTRUE_SMTP_PASS=${{ secrets.GOTRUE_SMTP_PASS }}/' .env
|
||||||
|
sed -i 's/GOTRUE_SMTP_ADMIN_EMAIL=.*/GOTRUE_SMTP_ADMIN_EMAIL=${{ secrets.GOTRUE_SMTP_ADMIN_EMAIL }}/' .env
|
||||||
|
sed -i 's/GOTRUE_REGISTERED_EMAIL=.*/GOTRUE_REGISTERED_EMAIL=$GOTRUE_REGISTERED_EMAIL/' .env
|
||||||
|
sed -i 's/GOTRUE_REGISTERED_PASSWORD=.*/GOTRUE_REGISTERED_PASSWORD=$GOTRUE_REGISTERED_PASSWORD/' .env
|
||||||
|
sed -i 's/GOTRUE_MAILER_AUTOCONFIRM=.*/GOTRUE_MAILER_AUTOCONFIRM=true/' .env
|
||||||
|
|
||||||
- name: Run Docker-Compose
|
- name: Run Docker-Compose
|
||||||
run: |
|
run: |
|
||||||
docker-compose up -d
|
docker-compose up -d
|
||||||
|
|
||||||
- name: Add registered user
|
- name: Add registered user
|
||||||
run: |
|
run: |
|
||||||
|
# temporary allow signup without email verification
|
||||||
export GOTRUE_MAILER_AUTOCONFIRM=true
|
export GOTRUE_MAILER_AUTOCONFIRM=true
|
||||||
docker-compose up -d
|
docker-compose up -d
|
||||||
|
|
||||||
|
sleep 5 # sometimes the gotrue server may not be ready yet
|
||||||
|
source .env
|
||||||
curl localhost:9998/signup \
|
curl localhost:9998/signup \
|
||||||
--data-raw '{"email":"xigahi8979@tipent.com","password":"Hello123!"}' \
|
--data-raw '{"email":"'"$GOTRUE_REGISTERED_EMAIL"'","password":"'"$GOTRUE_REGISTERED_PASSWORD"'"}' \
|
||||||
--header 'Content-Type: application/json'
|
--header 'Content-Type: application/json'
|
||||||
|
|
||||||
|
# revert to require signup email verification
|
||||||
export GOTRUE_MAILER_AUTOCONFIRM=false
|
export GOTRUE_MAILER_AUTOCONFIRM=false
|
||||||
docker-compose up -d
|
docker-compose up -d
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: |
|
run: |
|
||||||
|
cargo install sqlx-cli --version=${{ env.SQLX_VERSION }} --features ${{ env.SQLX_FEATURES }} --no-default-features --locked
|
||||||
|
cargo sqlx database create
|
||||||
|
cargo sqlx migrate run
|
||||||
cargo test
|
cargo test
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
name: Rust Lint
|
name: AppFlowy-Cloud Lint
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
|
@ -7,23 +7,41 @@ on:
|
||||||
types: [ opened, synchronize, reopened ]
|
types: [ opened, synchronize, reopened ]
|
||||||
branches: [ main ]
|
branches: [ main ]
|
||||||
|
|
||||||
|
env:
|
||||||
|
SQLX_VERSION: 0.7.1
|
||||||
|
SQLX_FEATURES: "rustls,postgres"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
|
name: Unit Tests
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: dtolnay/rust-toolchain@stable
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
with:
|
|
||||||
components: rustfmt,clippy
|
|
||||||
- uses: Swatinem/rust-cache@v2
|
- uses: Swatinem/rust-cache@v2
|
||||||
with:
|
with:
|
||||||
workspaces: |
|
workspaces: |
|
||||||
AppFlowy-Cloud
|
AppFlowy-Cloud
|
||||||
|
|
||||||
|
- name: Copy and rename dev.env to .env
|
||||||
|
run: cp dev.env .env
|
||||||
|
|
||||||
|
- name: Run the dependency services
|
||||||
|
run: docker-compose --file docker-compose-dev.yml up -d
|
||||||
|
|
||||||
|
- name: Install Development Dependencies
|
||||||
|
run: |
|
||||||
|
cargo install sqlx-cli --version=${{ env.SQLX_VERSION }} --features ${{ env.SQLX_FEATURES }} --no-default-features --locked
|
||||||
|
cargo sqlx database create
|
||||||
|
cargo sqlx migrate run
|
||||||
|
|
||||||
|
- name: Check sqlx-data.json
|
||||||
|
run: |
|
||||||
|
cargo sqlx prepare --check -- --bin appflowy_cloud
|
||||||
|
|
||||||
- name: Rustfmt
|
- name: Rustfmt
|
||||||
run: cargo fmt --check
|
run: cargo fmt --check
|
||||||
|
|
||||||
- name: Clippy
|
- name: Clippy
|
||||||
run: SQLX_OFFLINE=true cargo clippy -- -D warnings
|
run: SQLX_OFFLINE=true cargo clippy -- -D warnings
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,3 +11,4 @@ yarn.lock
|
||||||
node_modules
|
node_modules
|
||||||
**/crates/AppFlowy-Collab/
|
**/crates/AppFlowy-Collab/
|
||||||
data/
|
data/
|
||||||
|
.env
|
||||||
|
|
|
||||||
|
|
@ -456,6 +456,7 @@ dependencies = [
|
||||||
"config",
|
"config",
|
||||||
"dashmap",
|
"dashmap",
|
||||||
"derive_more",
|
"derive_more",
|
||||||
|
"dotenv",
|
||||||
"fancy-regex",
|
"fancy-regex",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"jsonwebtoken",
|
"jsonwebtoken",
|
||||||
|
|
@ -1119,6 +1120,12 @@ dependencies = [
|
||||||
"syn 2.0.28",
|
"syn 2.0.28",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dotenv"
|
||||||
|
version = "0.15.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dotenvy"
|
name = "dotenvy"
|
||||||
version = "0.15.7"
|
version = "0.15.7"
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ actix-identity = "0.5.2"
|
||||||
actix-cors = "0.6.4"
|
actix-cors = "0.6.4"
|
||||||
actix-session = { version = "0.7", features = ["redis-rs-tls-session"] }
|
actix-session = { version = "0.7", features = ["redis-rs-tls-session"] }
|
||||||
openssl = "0.10.45"
|
openssl = "0.10.45"
|
||||||
|
dotenv = "0.15.0"
|
||||||
|
|
||||||
# serde
|
# serde
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
|
|
|
||||||
105
README.md
105
README.md
|
|
@ -1,63 +1,94 @@
|
||||||
## Pre-requisites
|
# AppFlowy Cloud
|
||||||
|
- Cloud Server for AppFlowy
|
||||||
|
|
||||||
|
## Deployment
|
||||||
|
|
||||||
|
### Environmental Variables before starting
|
||||||
|
- you can set it explicitly(below) or in a `.env` file (use `dev.env`) as template
|
||||||
|
```bash
|
||||||
|
# authentication key, change this and keep the key safe and secret
|
||||||
|
GOTRUE_JWT_SECRET=secret_auth_pass
|
||||||
|
|
||||||
|
# enabled by default, if you dont want need email confirmation, set to false
|
||||||
|
GOTRUE_MAILER_AUTOCONFIRM=true
|
||||||
|
|
||||||
|
# if you enable mail confirmation, you need to set the SMTP configuration below
|
||||||
|
GOTRUE_SMTP_HOST=smtp.gmail.com
|
||||||
|
GOTRUE_SMTP_PORT=465
|
||||||
|
GOTRUE_SMTP_USER=email_sender@some_company.com
|
||||||
|
GOTRUE_SMTP_PASS=email_sender_password
|
||||||
|
GOTRUE_SMTP_ADMIN_EMAIL=comp_admin@@some_company.com
|
||||||
|
|
||||||
|
# Change 'localhost' to the public host of machine that is running on.
|
||||||
|
# This is for email confirmation link
|
||||||
|
API_EXTERNAL_URL=http://localhost:9998
|
||||||
|
```
|
||||||
|
- additional settings can be modified in `docker-compose.yml`
|
||||||
|
|
||||||
|
### Start Cloud Server
|
||||||
|
```bash
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ports
|
||||||
|
Host Server is required to expose the following Ports:
|
||||||
|
- `8000`
|
||||||
|
- `9998`
|
||||||
|
|
||||||
|
## Local Development
|
||||||
|
|
||||||
|
### Pre-requisites
|
||||||
|
|
||||||
You'll need to install:
|
You'll need to install:
|
||||||
|
|
||||||
- [Rust](https://www.rust-lang.org/tools/install)
|
- [Rust](https://www.rust-lang.org/tools/install)
|
||||||
- [Docker](https://docs.docker.com/get-docker/)
|
- [Docker](https://docs.docker.com/get-docker/)
|
||||||
|
|
||||||
Here are the Os-specific requirements:
|
### Configuration
|
||||||
|
- copy the configurations from `dev.env` to `.env`
|
||||||
### Windows
|
- edit the `.env` as required (such as SMTP configurations)
|
||||||
|
|
||||||
|
### Run the dependency servers
|
||||||
```bash
|
```bash
|
||||||
cargo install -f cargo-binutils
|
docker-compose --file docker-compose-dev.yml up -d
|
||||||
rustup component add llvm-tools-preview
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
### Install sqlx-cli
|
||||||
cargo install --version="~0.6" sqlx-cli --no-default-features --features rustls,postgres
|
|
||||||
```
|
|
||||||
|
|
||||||
### Linux
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Ubuntu
|
cargo install sqlx-cli
|
||||||
sudo apt-get install libssl-dev postgresql-client
|
|
||||||
# Arch
|
|
||||||
sudo pacman -S postgresql
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
### Run sqlx migration
|
||||||
cargo install --version="~0.6" sqlx-cli --no-default-features --features rustls,postgres
|
|
||||||
```
|
|
||||||
|
|
||||||
### MacOS
|
|
||||||
|
|
||||||
```
|
|
||||||
cargo install --version="~0.6" sqlx-cli --no-default-features --features rustls,postgres
|
|
||||||
```
|
|
||||||
|
|
||||||
## How to build
|
|
||||||
|
|
||||||
Run `the init_db.sh` to create a Postgres database container in Docker:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./build/init_database.sh
|
sqlx database create
|
||||||
|
sqlx migrate run
|
||||||
```
|
```
|
||||||
|
|
||||||
Run the `init_redis.sh` to create a Redis container in Docker:
|
### Run the AppFlowy-Cloud server
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./build/init_redis.sh
|
cargo run
|
||||||
```
|
```
|
||||||
|
|
||||||
Build the project:
|
### Run the tests
|
||||||
|
|
||||||
|
#### Verified user
|
||||||
|
- Make sure you have registered a user and put into your `.env` file, else some test may fail
|
||||||
|
- You may register the email defined in `.env` by running the following command, you may then click on the link sent to that email to complete registration
|
||||||
```bash
|
```bash
|
||||||
cargo build
|
source .env
|
||||||
|
curl localhost:9998/signup \
|
||||||
|
--data-raw '{"email":"'"$GOTRUE_REGISTERED_EMAIL"'","password":"'"$GOTRUE_REGISTERED_PASSWORD"'"}' \
|
||||||
|
--header 'Content-Type: application/json'
|
||||||
|
```
|
||||||
|
- Verify registration, you should get a token after running the command below:
|
||||||
|
```bash
|
||||||
|
source .env
|
||||||
|
curl localhost:9998/token?grant_type=password \
|
||||||
|
--data-raw '{"email":"'"$GOTRUE_REGISTERED_EMAIL"'","password":"'"$GOTRUE_REGISTERED_PASSWORD"'"}' \
|
||||||
|
--header 'Content-Type: application/json'
|
||||||
```
|
```
|
||||||
or you can try to run the tests in your local machine:
|
|
||||||
|
|
||||||
|
#### Test
|
||||||
```bash
|
```bash
|
||||||
cargo test
|
cargo test
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ then
|
||||||
-p "${DB_PORT}":5432 \
|
-p "${DB_PORT}":5432 \
|
||||||
-d \
|
-d \
|
||||||
--name "appflowy_postgres_$(date '+%s')" \
|
--name "appflowy_postgres_$(date '+%s')" \
|
||||||
postgres_with_pgjwt -N 1000
|
postgres:14 -N 1000
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,5 +15,4 @@ websocket:
|
||||||
client_timeout: 10
|
client_timeout: 10
|
||||||
redis_uri: "redis://127.0.0.1:6379"
|
redis_uri: "redis://127.0.0.1:6379"
|
||||||
gotrue:
|
gotrue:
|
||||||
base_url: "http://gotrue:9999"
|
base_url: "http://127.0.0.1:9999"
|
||||||
jwt_secret: "hello123"
|
|
||||||
|
|
|
||||||
|
|
@ -3,3 +3,8 @@ application:
|
||||||
base_url: "https://127.0.0.1"
|
base_url: "https://127.0.0.1"
|
||||||
database:
|
database:
|
||||||
require_ssl: false
|
require_ssl: false
|
||||||
|
port: 5433
|
||||||
|
redis_uri: "redis://127.0.0.1:6380"
|
||||||
|
gotrue:
|
||||||
|
base_url: "http://127.0.0.1:9998"
|
||||||
|
jwt_secret: "hello456"
|
||||||
|
|
|
||||||
|
|
@ -6,3 +6,5 @@ database:
|
||||||
port: 5432
|
port: 5432
|
||||||
require_ssl: false
|
require_ssl: false
|
||||||
redis_uri: "redis://redis:6379"
|
redis_uri: "redis://redis:6379"
|
||||||
|
gotrue:
|
||||||
|
base_url: "http://gotrue:9999"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
# This file is used to set the environment variables for local development
|
||||||
|
# Copy this file to .env and change the values as needed
|
||||||
|
|
||||||
|
# authentication key, change this and keep the key safe and secret
|
||||||
|
# self defined key, you can use any string
|
||||||
|
GOTRUE_JWT_SECRET=hello456
|
||||||
|
|
||||||
|
# user sign up will automatically be confirmed if this is set to true
|
||||||
|
GOTRUE_MAILER_AUTOCONFIRM=false
|
||||||
|
|
||||||
|
# if you enable mail confirmation, you need to set the SMTP configuration below
|
||||||
|
GOTRUE_SMTP_HOST=smtp.gmail.com
|
||||||
|
GOTRUE_SMTP_PORT=465
|
||||||
|
GOTRUE_SMTP_USER=email_sender@some_company.com
|
||||||
|
GOTRUE_SMTP_PASS=email_sender_password
|
||||||
|
GOTRUE_SMTP_ADMIN_EMAIL=comp_admin@@some_company.com
|
||||||
|
|
||||||
|
# clicking on email verification link will redirect to this host
|
||||||
|
API_EXTERNAL_URL=http://localhost:9998
|
||||||
|
|
||||||
|
# the account that the test will pick up as a registered user
|
||||||
|
GOTRUE_REGISTERED_EMAIL=your_email@some_company.com
|
||||||
|
GOTRUE_REGISTERED_PASSWORD=your_password
|
||||||
|
|
||||||
|
# url to the postgres database
|
||||||
|
DATABASE_URL=postgres://postgres:password@localhost:5433/appflowy
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
version: '3'
|
||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: docker/Dockerfile_postgres
|
||||||
|
environment:
|
||||||
|
- POSTGRES_USER=${POSTGRES_USER:-postgres}
|
||||||
|
- POSTGRES_DB=${POSTGRES_DB:-postgres}
|
||||||
|
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-password}
|
||||||
|
- POSTGRES_HOST=${POSTGRES_HOST:-postgres}
|
||||||
|
ports:
|
||||||
|
- 5433:5432
|
||||||
|
volumes:
|
||||||
|
- ./migrations:/docker-entrypoint-initdb.d
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: redis
|
||||||
|
ports:
|
||||||
|
- 6380:6379
|
||||||
|
|
||||||
|
gotrue:
|
||||||
|
image: supabase/gotrue
|
||||||
|
restart: on-failure
|
||||||
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
environment:
|
||||||
|
- GOTRUE_SITE_URL=appflowy-flutter:// # redirected to AppFlowy application
|
||||||
|
- GOTRUE_JWT_SECRET=${GOTRUE_JWT_SECRET} # authentication secret
|
||||||
|
- GOTRUE_DB_DRIVER=postgres
|
||||||
|
- API_EXTERNAL_URL=${API_EXTERNAL_URL:-http://localhost:9998} # change 'localhost' to the public host of machine that is running on
|
||||||
|
- DATABASE_URL=postgres://supabase_auth_admin:root@postgres:5432/postgres
|
||||||
|
- PORT=9999
|
||||||
|
- GOTRUE_SMTP_HOST=${GOTRUE_SMTP_HOST:-} # e.g. smtp.gmail.com
|
||||||
|
- GOTRUE_SMTP_PORT=${GOTRUE_SMTP_PORT:-} # e.g. 465
|
||||||
|
- GOTRUE_SMTP_USER=${GOTRUE_SMTP_USER:-} # email sender, e.g. noreply@appflowy.io
|
||||||
|
- GOTRUE_SMTP_PASS=${GOTRUE_SMTP_PASS:-} # email password
|
||||||
|
- GOTRUE_SMTP_ADMIN_EMAIL=${GOTRUE_SMTP_ADMIN_EMAIL:-} # email with admin privileges e.g. internal@appflowy.io
|
||||||
|
- GOTRUE_SMTP_MAX_FREQUENCY=${GOTRUE_SMTP_MAX_FREQUENCY:-1ns} # set to 1ns for running tests
|
||||||
|
- GOTRUE_MAILER_URLPATHS_CONFIRMATION=/verify
|
||||||
|
- GOTRUE_MAILER_AUTOCONFIRM=${GOTRUE_MAILER_AUTOCONFIRM:-false} # change this to true to skip email confirmation
|
||||||
|
ports:
|
||||||
|
- 9998:9999
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
version: '3'
|
version: '3'
|
||||||
services:
|
services:
|
||||||
postgres:
|
postgres:
|
||||||
image: postgres
|
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: docker/Dockerfile_postgres
|
dockerfile: docker/Dockerfile_postgres
|
||||||
|
|
@ -26,21 +25,20 @@ services:
|
||||||
depends_on:
|
depends_on:
|
||||||
- postgres
|
- postgres
|
||||||
environment:
|
environment:
|
||||||
- GOTRUE_SITE_URL=http://localhost:3000 # redirected site
|
- GOTRUE_SITE_URL=appflowy-flutter:// # redirected to AppFlowy application
|
||||||
- GOTRUE_JWT_SECRET=${GOTRUE_JWT_SECRET:-hello123}
|
- GOTRUE_JWT_SECRET=${GOTRUE_JWT_SECRET} # authentication secret
|
||||||
- GOTRUE_DB_DRIVER=postgres
|
- GOTRUE_DB_DRIVER=postgres
|
||||||
|
- API_EXTERNAL_URL=${API_EXTERNAL_URL:-http://localhost:9998} # change 'localhost' to the public host of machine that is running on
|
||||||
- DATABASE_URL=postgres://supabase_auth_admin:root@postgres:5432/postgres
|
- DATABASE_URL=postgres://supabase_auth_admin:root@postgres:5432/postgres
|
||||||
- API_EXTERNAL_URL=http://localhost:9998 # verify site
|
|
||||||
- PORT=9999
|
- PORT=9999
|
||||||
- GOTRUE_SMTP_HOST=smtp.gmail.com
|
- GOTRUE_SMTP_HOST=${GOTRUE_SMTP_HOST:-} # e.g. smtp.gmail.com
|
||||||
- GOTRUE_SMTP_PORT=465
|
- GOTRUE_SMTP_PORT=${GOTRUE_SMTP_PORT:-} # e.g. 465
|
||||||
- GOTRUE_SMTP_USER=noreply@appflowy.io
|
- GOTRUE_SMTP_USER=${GOTRUE_SMTP_USER:-} # email sender, e.g. noreply@appflowy.io
|
||||||
- GOTRUE_SMTP_PASS=${GOTRUE_SMTP_PASS:-}
|
- GOTRUE_SMTP_PASS=${GOTRUE_SMTP_PASS:-} # email password
|
||||||
- GOTRUE_SMTP_ADMIN_EMAIL=internal@appflowy.io
|
- GOTRUE_SMTP_ADMIN_EMAIL=${GOTRUE_SMTP_ADMIN_EMAIL:-} # email with admin privileges e.g. internal@appflowy.io
|
||||||
- GOTRUE_RATE_LIMIT_EMAIL_SENT=${GOTRUE_RATE_LIMIT_EMAIL_SENT:-100000}
|
- GOTRUE_SMTP_MAX_FREQUENCY=${GOTRUE_SMTP_MAX_FREQUENCY:-1ns} # set to 1ns for running tests
|
||||||
- GOTRUE_SMTP_MAX_FREQUENCY=1ns
|
|
||||||
- GOTRUE_MAILER_URLPATHS_CONFIRMATION=/verify
|
- GOTRUE_MAILER_URLPATHS_CONFIRMATION=/verify
|
||||||
- GOTRUE_MAILER_AUTOCONFIRM=${GOTRUE_MAILER_AUTOCONFIRM:-false}
|
- GOTRUE_MAILER_AUTOCONFIRM=${GOTRUE_MAILER_AUTOCONFIRM:-false} # change this to true to skip email confirmation
|
||||||
ports:
|
ports:
|
||||||
- 9998:9999
|
- 9998:9999
|
||||||
|
|
||||||
|
|
@ -48,6 +46,7 @@ services:
|
||||||
restart: on-failure
|
restart: on-failure
|
||||||
environment:
|
environment:
|
||||||
- APP_ENVIRONMENT=production
|
- APP_ENVIRONMENT=production
|
||||||
|
- APP__GOTRUE__JWT_SECRET=${GOTRUE_JWT_SECRET}
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: docker/Dockerfile
|
dockerfile: docker/Dockerfile
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
|
use futures_util::TryFutureExt;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
grant::Grant,
|
grant::Grant,
|
||||||
models::{AccessTokenResponse, GoTrueError, OAuthError, TokenResult, User},
|
models::{AccessTokenResponse, GoTrueError, GoTrueSettings, OAuthError, TokenResult, User},
|
||||||
};
|
};
|
||||||
use crate::utils::http_response::{check_response, from_body, from_response};
|
use crate::utils::http_response::{check_response, from_body, from_response};
|
||||||
|
|
||||||
|
|
@ -19,14 +20,35 @@ impl Client {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn settings(&self) -> Result<GoTrueSettings, Error> {
|
||||||
|
let url: String = format!("{}/settings", self.base_url);
|
||||||
|
let resp = self.client.get(url).send().await?;
|
||||||
|
from_response(resp).await
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn sign_up(&self, email: &str, password: &str) -> Result<User, Error> {
|
pub async fn sign_up(&self, email: &str, password: &str) -> Result<User, Error> {
|
||||||
let payload = serde_json::json!({
|
let payload = serde_json::json!({
|
||||||
"email": email,
|
"email": email,
|
||||||
"password": password,
|
"password": password,
|
||||||
});
|
});
|
||||||
let url: String = format!("{}/signup", self.base_url);
|
let url: String = format!("{}/signup", self.base_url);
|
||||||
let resp = self.client.post(url).json(&payload).send().await?;
|
|
||||||
from_response(resp).await
|
let (settings, resp) = tokio::try_join!(
|
||||||
|
self.settings(),
|
||||||
|
self
|
||||||
|
.client
|
||||||
|
.post(&url)
|
||||||
|
.json(&payload)
|
||||||
|
.send()
|
||||||
|
.map_err(Error::from),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
if settings.mailer_autoconfirm {
|
||||||
|
let token: AccessTokenResponse = from_response(resp).await?;
|
||||||
|
Ok(token.user)
|
||||||
|
} else {
|
||||||
|
from_response(resp).await
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn token(&self, grant: &Grant) -> Result<TokenResult, Error> {
|
pub async fn token(&self, grant: &Grant) -> Result<TokenResult, Error> {
|
||||||
|
|
|
||||||
|
|
@ -94,3 +94,39 @@ pub struct GoTrueError {
|
||||||
pub msg: String,
|
pub msg: String,
|
||||||
pub error_id: Option<String>,
|
pub error_id: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct GoTrueSettings {
|
||||||
|
pub external: GoTrueProviderSettings,
|
||||||
|
pub disable_signup: bool,
|
||||||
|
pub mailer_autoconfirm: bool,
|
||||||
|
pub phone_autoconfirm: bool,
|
||||||
|
pub sms_provider: String,
|
||||||
|
pub mfa_enabled: Option<bool>, // older versions of GoTrue do not return this
|
||||||
|
pub saml_enabled: Option<bool>, // older versions of GoTrue do not return this
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct GoTrueProviderSettings {
|
||||||
|
pub apple: bool,
|
||||||
|
pub azure: bool,
|
||||||
|
pub bitbucket: bool,
|
||||||
|
pub discord: bool,
|
||||||
|
pub facebook: bool,
|
||||||
|
pub figma: Option<bool>, // older versions of GoTrue do not return this
|
||||||
|
pub github: bool,
|
||||||
|
pub gitlab: bool,
|
||||||
|
pub google: bool,
|
||||||
|
pub keycloak: bool,
|
||||||
|
pub kakao: Option<bool>, // older versions of GoTrue do not return this
|
||||||
|
pub linkedin: bool,
|
||||||
|
pub notion: bool,
|
||||||
|
pub spotify: bool,
|
||||||
|
pub slack: bool,
|
||||||
|
pub workos: bool,
|
||||||
|
pub twitch: bool,
|
||||||
|
pub twitter: bool,
|
||||||
|
pub email: bool,
|
||||||
|
pub phone: bool,
|
||||||
|
pub zoom: bool,
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
# Cloud Test
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
- docker-compose
|
||||||
|
- SMTP server
|
||||||
|
- enviromental variables
|
||||||
|
```bash
|
||||||
|
# put in .env in the same directory
|
||||||
|
GOTRUE_JWT_SECRET=some_secret_key # self defined
|
||||||
|
GOTRUE_SMTP_HOST=smtp.gmail.com # using gmail smtp as example, change if needed
|
||||||
|
GOTRUE_SMTP_PORT=465
|
||||||
|
GOTRUE_SMTP_USER=email_sender@some_company.com
|
||||||
|
GOTRUE_SMTP_PASS=email_sender_password
|
||||||
|
GOTRUE_SMTP_ADMIN_EMAIL=comp_admin@@some_company.com
|
||||||
|
# GOTRUE_MAILER_AUTOCONFIRM false
|
||||||
|
|
||||||
|
GOTRUE_REGISTERED_EMAIL=your_email@some_company.com
|
||||||
|
GOTRUE_REGISTERED_PASSWORD=your_password
|
||||||
|
```
|
||||||
|
|
||||||
|
## Steps
|
||||||
|
|
||||||
|
### 1. Start the docker-compose
|
||||||
|
- `docker-compose up -d`
|
||||||
|
|
||||||
|
### 2. Create registered user
|
||||||
|
|
||||||
|
#### Manual
|
||||||
|
- send link to your email
|
||||||
|
```bash
|
||||||
|
curl localhost:9998/signup \
|
||||||
|
--data-raw '{"email":"'"$GOTRUE_REGISTERED_EMAIL"'","password":"'"$GOTRUE_REGISTERED_PASSWORD"'"}' \
|
||||||
|
--header 'Content-Type: application/json'
|
||||||
|
```
|
||||||
|
- click on the link
|
||||||
|
|
||||||
|
#### Auto
|
||||||
|
- skips the clicking on email
|
||||||
|
```bash
|
||||||
|
export GOTRUE_MAILER_AUTOCONFIRM=true
|
||||||
|
docker-compose up -d
|
||||||
|
source .env
|
||||||
|
curl localhost:9998/signup \
|
||||||
|
--data-raw '{"email":"'"$GOTRUE_REGISTERED_EMAIL"'","password":"'"$GOTRUE_REGISTERED_PASSWORD"'"}' \
|
||||||
|
--header 'Content-Type: application/json'
|
||||||
|
|
||||||
|
export GOTRUE_MAILER_AUTOCONFIRM=false
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Run test
|
||||||
|
- `cargo test`
|
||||||
|
|
@ -69,7 +69,7 @@ async fn sign_in_success() {
|
||||||
let mut c = Client::from(reqwest::Client::new(), LOCALHOST_URL);
|
let mut c = Client::from(reqwest::Client::new(), LOCALHOST_URL);
|
||||||
|
|
||||||
let resp = c
|
let resp = c
|
||||||
.sign_in_password(REGISTERED_EMAIL, REGISTERED_PASSWORD)
|
.sign_in_password(®ISTERED_EMAIL, ®ISTERED_PASSWORD)
|
||||||
.await;
|
.await;
|
||||||
let resp = resp.unwrap();
|
let resp = resp.unwrap();
|
||||||
match resp {
|
match resp {
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ async fn sign_out_but_not_sign_in() {
|
||||||
async fn sign_out_after_sign_in() {
|
async fn sign_out_after_sign_in() {
|
||||||
let mut c = Client::from(reqwest::Client::new(), LOCALHOST_URL);
|
let mut c = Client::from(reqwest::Client::new(), LOCALHOST_URL);
|
||||||
|
|
||||||
c.sign_in_password(REGISTERED_EMAIL, REGISTERED_PASSWORD)
|
c.sign_in_password(®ISTERED_EMAIL, ®ISTERED_PASSWORD)
|
||||||
.await
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,11 @@ async fn update_but_not_logged_in() {
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn update_password_same_password() {
|
async fn update_password_same_password() {
|
||||||
let mut c = Client::from(reqwest::Client::new(), LOCALHOST_URL);
|
let mut c = Client::from(reqwest::Client::new(), LOCALHOST_URL);
|
||||||
c.sign_in_password(REGISTERED_EMAIL, REGISTERED_PASSWORD)
|
c.sign_in_password(®ISTERED_EMAIL, ®ISTERED_PASSWORD)
|
||||||
.await
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
c.update(REGISTERED_EMAIL, REGISTERED_PASSWORD)
|
c.update(®ISTERED_EMAIL, ®ISTERED_PASSWORD)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
@ -32,20 +32,20 @@ async fn update_password_and_revert() {
|
||||||
{
|
{
|
||||||
// change password to new_password
|
// change password to new_password
|
||||||
let mut c = Client::from(reqwest::Client::new(), LOCALHOST_URL);
|
let mut c = Client::from(reqwest::Client::new(), LOCALHOST_URL);
|
||||||
c.sign_in_password(REGISTERED_EMAIL, REGISTERED_PASSWORD)
|
c.sign_in_password(®ISTERED_EMAIL, ®ISTERED_PASSWORD)
|
||||||
.await
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
c.update(REGISTERED_EMAIL, new_password).await.unwrap();
|
c.update(®ISTERED_EMAIL, new_password).await.unwrap();
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// revert password to old_password
|
// revert password to old_password
|
||||||
let mut c = Client::from(reqwest::Client::new(), LOCALHOST_URL);
|
let mut c = Client::from(reqwest::Client::new(), LOCALHOST_URL);
|
||||||
c.sign_in_password(REGISTERED_EMAIL, new_password)
|
c.sign_in_password(®ISTERED_EMAIL, new_password)
|
||||||
.await
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
c.update(REGISTERED_EMAIL, REGISTERED_PASSWORD)
|
c.update(®ISTERED_EMAIL, ®ISTERED_PASSWORD)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,18 @@
|
||||||
|
use dotenv::dotenv;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
|
||||||
pub const REGISTERED_EMAIL: &str = "xigahi8979@tipent.com";
|
use lazy_static::lazy_static;
|
||||||
pub const REGISTERED_PASSWORD: &str = "Hello123!";
|
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref REGISTERED_EMAIL: String = {
|
||||||
|
dotenv().ok();
|
||||||
|
std::env::var("GOTRUE_REGISTERED_EMAIL").unwrap()
|
||||||
|
};
|
||||||
|
pub static ref REGISTERED_PASSWORD: String = {
|
||||||
|
dotenv().ok();
|
||||||
|
std::env::var("GOTRUE_REGISTERED_PASSWORD").unwrap()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub fn timestamp_nano() -> u128 {
|
pub fn timestamp_nano() -> u128 {
|
||||||
SystemTime::now()
|
SystemTime::now()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
mod settings;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
use appflowy_cloud::component::auth::gotrue::api::Client;
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn gotrue_settings() {
|
||||||
|
let http_client = reqwest::Client::new();
|
||||||
|
let gotrue_client = Client::new(http_client, "http://localhost:9998");
|
||||||
|
gotrue_client.settings().await.unwrap();
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
// mod api;
|
// mod api;
|
||||||
mod client;
|
mod client;
|
||||||
|
mod gotrue;
|
||||||
// mod realtime;
|
// mod realtime;
|
||||||
// mod util;
|
// mod util;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue