diff --git a/.sqlx/query-884c44d3a87ca4e520f9e8cec6ba673ea4e196920636e4a4db9d42fad3ef4d73.json b/.sqlx/query-884c44d3a87ca4e520f9e8cec6ba673ea4e196920636e4a4db9d42fad3ef4d73.json
deleted file mode 100644
index aafc6f23..00000000
--- a/.sqlx/query-884c44d3a87ca4e520f9e8cec6ba673ea4e196920636e4a4db9d42fad3ef4d73.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "db_name": "PostgreSQL",
- "query": "\n UPDATE auth.users\n SET role = 'supabase_admin', email_confirmed_at = NOW()\n WHERE id = $1\n ",
- "describe": {
- "columns": [],
- "parameters": {
- "Left": [
- "Uuid"
- ]
- },
- "nullable": []
- },
- "hash": "884c44d3a87ca4e520f9e8cec6ba673ea4e196920636e4a4db9d42fad3ef4d73"
-}
diff --git a/deploy.env b/deploy.env
index afae1ebf..5b4a4f47 100644
--- a/deploy.env
+++ b/deploy.env
@@ -56,11 +56,14 @@ GOTRUE_SMTP_USER=email_sender@some_company.com
GOTRUE_SMTP_PASS=email_sender_password
GOTRUE_SMTP_ADMIN_EMAIL=comp_admin@some_company.com
-# This user will be created when AppFlowy Cloud starts successfully
+# This user will be created when GoTrue starts successfully
# You can use this user to login to the admin panel
GOTRUE_ADMIN_EMAIL=admin@example.com
GOTRUE_ADMIN_PASSWORD=password
+# Set this to true if users can only join by invite
+GOTRUE_DISABLE_SIGNUP=false
+
# User will be redirected to this after Email or OAuth login
# Change this to your own domain where you host the docker-compose or gotrue
# If you are using a different domain, you need to change the redirect_uri in the OAuth2 configuration
diff --git a/dev.env b/dev.env
index 57c52fcf..15002a98 100644
--- a/dev.env
+++ b/dev.env
@@ -39,6 +39,9 @@ GOTRUE_MAILER_TEMPLATES_EMAIL_CHANGE=https://raw.githubusercontent.com/AppFlowy-
GOTRUE_ADMIN_EMAIL=admin@example.com
GOTRUE_ADMIN_PASSWORD=password
+# Set this to true if users can only join by invite
+GOTRUE_DISABLE_SIGNUP=false
+
# The email verification link provided to users will redirect them to this specified host.
# You should update this setting to reflect the domain where you are hosting your application with docker-compose or gotrue.
# If you're using an Nginx proxy as part of your setup, this host should be set to the domain managed by the proxy.
diff --git a/docker-compose-ci.yml b/docker-compose-ci.yml
index b56851b9..c9f1c5cb 100644
--- a/docker-compose-ci.yml
+++ b/docker-compose-ci.yml
@@ -33,6 +33,11 @@ services:
image: pgvector/pgvector:pg16
ports:
- "5432:5432"
+ healthcheck:
+ test: ["CMD", "pg_isready", "-U", "${POSTGRES_USER}"]
+ interval: 5s
+ timeout: 5s
+ retries: 6
environment:
- POSTGRES_USER=${POSTGRES_USER:-postgres}
- POSTGRES_DB=${POSTGRES_DB:-postgres}
@@ -50,14 +55,28 @@ services:
gotrue:
restart: on-failure
- image: supabase/gotrue:v2.159.1
+ image: appflowyinc/gotrue:${GOTRUE_VERSION:-latest}
+ depends_on:
+ postgres:
+ condition: service_healthy
+ healthcheck:
+ test: ["CMD", "nc", "-z", "localhost", "9999"]
+ interval: 5s
+ timeout: 5s
+ retries: 6
environment:
# There are a lot of options to configure GoTrue. You can reference the example config:
# https://github.com/supabase/gotrue/blob/master/example.env
+ - GOTRUE_ADMIN_EMAIL=${GOTRUE_ADMIN_EMAIL}
+ - GOTRUE_ADMIN_PASSWORD=${GOTRUE_ADMIN_PASSWORD}
+ - GOTRUE_DISABLE_SIGNUP=${GOTRUE_DISABLE_SIGNUP:-false}
- GOTRUE_SITE_URL=appflowy-flutter:// # redirected to AppFlowy application
- URI_ALLOW_LIST=* # adjust restrict if necessary
- GOTRUE_JWT_SECRET=${GOTRUE_JWT_SECRET} # authentication secret
- GOTRUE_JWT_EXP=${GOTRUE_JWT_EXP}
+ # Without this environment variable, the createuser command will create an admin
+ # with the `admin` role as opposed to `supabase_admin`
+ - GOTRUE_JWT_ADMIN_GROUP_NAME=supabase_admin
- GOTRUE_DB_DRIVER=postgres
- API_EXTERNAL_URL=${API_EXTERNAL_URL}
- DATABASE_URL=${GOTRUE_DATABASE_URL}
@@ -122,6 +141,9 @@ services:
FEATURES: ""
PROFILE: ci
image: appflowyinc/appflowy_cloud:${APPFLOWY_CLOUD_VERSION:-latest}
+ depends_on:
+ gotrue:
+ condition: service_healthy
admin_frontend:
restart: on-failure
diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml
index 1f314aae..4f6cbcd9 100644
--- a/docker-compose-dev.yml
+++ b/docker-compose-dev.yml
@@ -43,15 +43,21 @@ services:
gotrue:
restart: on-failure
- image: supabase/gotrue:v2.159.1
+ image: appflowyinc/gotrue:${GOTRUE_VERSION:-latest}
depends_on:
- postgres
environment:
# Gotrue config: https://github.com/supabase/gotrue/blob/master/example.env
+ - GOTRUE_ADMIN_EMAIL=${GOTRUE_ADMIN_EMAIL}
+ - GOTRUE_ADMIN_PASSWORD=${GOTRUE_ADMIN_PASSWORD}
+ - GOTRUE_DISABLE_SIGNUP=${GOTRUE_DISABLE_SIGNUP:-false}
- GOTRUE_SITE_URL=appflowy-flutter:// # redirected to AppFlowy application
- URI_ALLOW_LIST=* # adjust restrict if necessary
- GOTRUE_JWT_SECRET=${GOTRUE_JWT_SECRET} # authentication secret
- GOTRUE_JWT_EXP=${GOTRUE_JWT_EXP}
+ # Without this environment variable, the createuser command will create an admin
+ # with the `admin` role as opposed to `supabase_admin`
+ - GOTRUE_JWT_ADMIN_GROUP_NAME=supabase_admin
- GOTRUE_DB_DRIVER=postgres
- API_EXTERNAL_URL=${API_EXTERNAL_URL}
- DATABASE_URL=${GOTRUE_DATABASE_URL}
diff --git a/docker-compose.yml b/docker-compose.yml
index b39056cd..23bf7182 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -33,6 +33,11 @@ services:
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-password}
- POSTGRES_HOST=${POSTGRES_HOST:-postgres}
- SUPABASE_PASSWORD=${SUPABASE_PASSWORD:-root}
+ healthcheck:
+ test: ["CMD", "pg_isready", "-U", "${POSTGRES_USER}"]
+ interval: 5s
+ timeout: 5s
+ retries: 6
volumes:
- ./migrations/before:/docker-entrypoint-initdb.d
- postgres_data:/var/lib/postgresql/data
@@ -46,14 +51,28 @@ services:
build:
context: docker/gotrue
dockerfile: Dockerfile
+ depends_on:
+ postgres:
+ condition: service_healthy
+ healthcheck:
+ test: ["CMD", "nc", "-z", "localhost", "9999"]
+ interval: 5s
+ timeout: 5s
+ retries: 6
image: appflowyinc/gotrue:${GOTRUE_VERSION:-latest}
environment:
# There are a lot of options to configure GoTrue. You can reference the example config:
# https://github.com/supabase/gotrue/blob/master/example.env
+ - GOTRUE_ADMIN_EMAIL=${GOTRUE_ADMIN_EMAIL}
+ - GOTRUE_ADMIN_PASSWORD=${GOTRUE_ADMIN_PASSWORD}
+ - GOTRUE_DISABLE_SIGNUP=${GOTRUE_DISABLE_SIGNUP:-false}
- GOTRUE_SITE_URL=appflowy-flutter:// # redirected to AppFlowy application
- URI_ALLOW_LIST=* # adjust restrict if necessary
- GOTRUE_JWT_SECRET=${GOTRUE_JWT_SECRET} # authentication secret
- GOTRUE_JWT_EXP=${GOTRUE_JWT_EXP}
+ # Without this environment variable, the createuser command will create an admin
+ # with the `admin` role as opposed to `supabase_admin`
+ - GOTRUE_JWT_ADMIN_GROUP_NAME=supabase_admin
- GOTRUE_DB_DRIVER=postgres
- API_EXTERNAL_URL=${API_EXTERNAL_URL}
- DATABASE_URL=${GOTRUE_DATABASE_URL}
diff --git a/src/application.rs b/src/application.rs
index a85fd5f6..be9a2e62 100644
--- a/src/application.rs
+++ b/src/application.rs
@@ -32,7 +32,7 @@ use openssl::x509::X509;
use secrecy::{ExposeSecret, Secret};
use sqlx::{postgres::PgPoolOptions, PgPool};
use tokio::sync::RwLock;
-use tracing::{error, info, warn};
+use tracing::{error, info};
use appflowy_ai_client::client::AppFlowyAIClient;
use appflowy_collaborate::actix_ws::server::RealtimeServerActor;
@@ -43,7 +43,6 @@ use appflowy_collaborate::indexer::IndexerProvider;
use appflowy_collaborate::snapshot::SnapshotControl;
use appflowy_collaborate::CollaborationServer;
use database::file::s3_client_impl::{AwsS3BucketClientImpl, S3BucketStorage};
-use gotrue::grant::{Grant, PasswordGrant};
use mailer::sender::Mailer;
use snowflake::Snowflake;
use tonic_proto::history::history_client::HistoryClient;
@@ -240,7 +239,7 @@ pub async fn init_state(config: &Config, rt_cmd_tx: CLCommandSender) -> Result Result Result {
+) -> GoTrueAdmin {
let admin_email = gotrue_setting.admin_email.as_str();
let password = gotrue_setting.admin_password.expose_secret();
- let gotrue_admin = GoTrueAdmin::new(
+ GoTrueAdmin::new(
admin_email.to_owned(),
password.to_owned(),
gotrue_client.clone(),
- );
-
- match gotrue_client
- .token(&Grant::Password(PasswordGrant {
- email: admin_email.to_owned(),
- password: password.clone(),
- }))
- .await
- {
- Ok(_token) => return Ok(gotrue_admin),
- Err(err) => tracing::warn!("Failed to get token: {:?}", err),
- };
-
- let res_resp = gotrue_client.sign_up(admin_email, password, None).await;
- match res_resp {
- Err(err) => {
- if let app_error::gotrue::GoTrueError::Internal(err) = err {
- match (err.code, err.msg.as_str()) {
- (400..=499, "User already registered") => {
- info!("Admin user already registered");
- Ok(gotrue_admin)
- },
- _ => Err(err.into()),
- }
- } else {
- Err(err.into())
- }
- },
- Ok(resp) => {
- let admin_user = {
- match resp {
- gotrue_entity::dto::SignUpResponse::Authenticated(resp) => resp.user,
- gotrue_entity::dto::SignUpResponse::NotAuthenticated(user) => user,
- }
- };
- match admin_user.role.as_str() {
- "supabase_admin" => {
- info!("Admin user already created and set role to supabase_admin");
- Ok(gotrue_admin)
- },
- _ => {
- let user_id = admin_user.id.parse::()?;
- let result = sqlx::query!(
- r#"
- UPDATE auth.users
- SET role = 'supabase_admin', email_confirmed_at = NOW()
- WHERE id = $1
- "#,
- user_id,
- )
- .execute(pg_pool)
- .await
- .context("failed to update the admin user")?;
-
- if result.rows_affected() != 1 {
- warn!("Failed to update the admin user");
- } else {
- info!("Admin user created and set role to supabase_admin");
- }
-
- Ok(gotrue_admin)
- },
- }
- },
- }
+ )
}
async fn get_redis_client(redis_uri: &str) -> Result {