From b785b1a4821cfd3de3e3cf455103734d49e0bb62 Mon Sep 17 00:00:00 2001 From: Fu Zi Xiang Date: Mon, 6 Nov 2023 13:50:38 +0800 Subject: [PATCH 1/8] fix: restartable server when autoconfirm is true --- ...d6290b7d73425f82bcf63ad4a0bd6959047d5.json | 14 ++++++ dev.env | 4 +- doc/deployment.md | 9 ++-- src/application.rs | 50 ++++++++++++------- 4 files changed, 52 insertions(+), 25 deletions(-) create mode 100644 .sqlx/query-141454ccce32ab6abd9fba21292d6290b7d73425f82bcf63ad4a0bd6959047d5.json diff --git a/.sqlx/query-141454ccce32ab6abd9fba21292d6290b7d73425f82bcf63ad4a0bd6959047d5.json b/.sqlx/query-141454ccce32ab6abd9fba21292d6290b7d73425f82bcf63ad4a0bd6959047d5.json new file mode 100644 index 00000000..6c359972 --- /dev/null +++ b/.sqlx/query-141454ccce32ab6abd9fba21292d6290b7d73425f82bcf63ad4a0bd6959047d5.json @@ -0,0 +1,14 @@ +{ + "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": "141454ccce32ab6abd9fba21292d6290b7d73425f82bcf63ad4a0bd6959047d5" +} diff --git a/dev.env b/dev.env index eaa905f8..c21673b6 100644 --- a/dev.env +++ b/dev.env @@ -6,7 +6,9 @@ GOTRUE_JWT_SECRET=hello456 # user sign up will automatically be confirmed if this is set to true -GOTRUE_MAILER_AUTOCONFIRM=false +# if you have OAuth2 set up or smtp configured, you can set this to false +# to enforce email confirmation or OAuth2 login instead +GOTRUE_MAILER_AUTOCONFIRM=true # if you enable mail confirmation, you need to set the SMTP configuration below GOTRUE_SMTP_HOST=smtp.gmail.com diff --git a/doc/deployment.md b/doc/deployment.md index a9cd989c..eb9d55c1 100644 --- a/doc/deployment.md +++ b/doc/deployment.md @@ -36,11 +36,10 @@ cp dev.env .env # This is the secret key for authentication, please change this and keep the key safe GOTRUE_JWT_SECRET=hello456 -# This determine if the user will be user automatically be confirmed when they sign up -# If this is enabled, it requires a clicking a confirmation link in the email which user -# use for sign up. -# Pre-requisite if you enable: you need to have your SMTP Service set up, -# which you can then fill in the details below +# This determine if the user will be user automatically be confirmed(verified) when they sign up +# If this is enabled, it requires a clicking a confirmation link in the email after a user signs up. +# If you do not have SMTP service set up, or any other OAuth2 method, you should set this to true, +# or else no user will be able to be authenticated GOTRUE_MAILER_AUTOCONFIRM=true # if you enable mail confirmation, you need to set the SMTP configuration below diff --git a/src/application.rs b/src/application.rs index 1265b345..885c11df 100644 --- a/src/application.rs +++ b/src/application.rs @@ -213,26 +213,38 @@ async fn setup_admin_account( ) -> Result<(), Error> { let admin_email = gotrue_setting.admin_email.as_str(); let password = gotrue_setting.admin_password.as_str(); - gotrue_client - .sign_up(admin_email, password) - .await - .context("failed to sign-up for admin user")?; + let res_resp = gotrue_client.sign_up(admin_email, password).await; - // Unable to use query! macro here instead - // because of the auth is a not default schema - // hopefully this will be fixed in the future - sqlx::query( - r#" - UPDATE auth.users - SET role = 'supabase_admin', email_confirmed_at = NOW() - WHERE email = $1 - "#, - ) - .bind(admin_email) - .execute(pg_pool) - .await - .context("failed to update the admin user")?; - Ok(()) + match res_resp { + Ok(resp) => match resp { + gotrue_entity::dto::SignUpResponse::Authenticated(_) => { + tracing::info!("Admin user already authenticated"); + Ok(()) + }, + gotrue_entity::dto::SignUpResponse::NotAuthenticated(user) => { + let user_id = user.id.parse::().unwrap(); + sqlx::query!( + r#" + UPDATE auth.users + SET role = 'supabase_admin', email_confirmed_at = NOW() + WHERE id = $1 + "#, user_id + ) + // .bind(user.id) + .execute(pg_pool) + .await + .context("failed to update the admin user")?; + Ok(()) + }, + }, + Err(err) => match (err.code, err.msg.as_str()) { + (400, "User already registered") => { + tracing::info!("Admin user already registered"); + Ok(()) + }, + _ => Err(err.into()), + }, + } } async fn get_redis_client(redis_uri: &str) -> Result { From a6f7198443438f5dfe78f4d318cd0a326ae2ff45 Mon Sep 17 00:00:00 2001 From: Fu Zi Xiang Date: Mon, 6 Nov 2023 13:54:45 +0800 Subject: [PATCH 2/8] chore: remove unneeded binding --- src/application.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/application.rs b/src/application.rs index 885c11df..fc973362 100644 --- a/src/application.rs +++ b/src/application.rs @@ -228,9 +228,9 @@ async fn setup_admin_account( UPDATE auth.users SET role = 'supabase_admin', email_confirmed_at = NOW() WHERE id = $1 - "#, user_id + "#, + user_id ) - // .bind(user.id) .execute(pg_pool) .await .context("failed to update the admin user")?; From 87049aa4982abf37de5edfb2c43592440edae5c2 Mon Sep 17 00:00:00 2001 From: Fu Zi Xiang Date: Mon, 6 Nov 2023 15:58:15 +0800 Subject: [PATCH 3/8] fix: added permission fix for container logs --- doc/logging.md | 12 +++++++++--- docker/filebeat/grant_container_logs_permissions.sh | 8 ++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) create mode 100755 docker/filebeat/grant_container_logs_permissions.sh diff --git a/doc/logging.md b/doc/logging.md index eb60d40a..d9203397 100644 --- a/doc/logging.md +++ b/doc/logging.md @@ -21,11 +21,17 @@ Exiting: error loading config file: config file ("filebeat.yml") can only be wri - Solution: remove write permission on the file: `chmod -w docker/filebeat/filebeat.yml` ### No Logs +- Observation: There are no logs in OpenSearch Dashboard +- Possibe Diagnostic: No read permission for `*.log` files in `/var/lib/docker/containers` + +- One Time Solution: give read permission to docker logs ``` -$ docker logs appflowy-cloud-filebeat-1 -...Non-zero metrics in the last 30s... +chmod -R a+r /var/lib/docker/containers ``` -- Solution: give read permission to docker logs: `chmod -R a+r /var/lib/docker/containers` +- Permanent Solution: give read permission to docker logs every time there's a modification +In the project root directory: `sudo ./docker/filebeat/grant_container_logs_permissions.sh` + - Caveat: Only work on unix like operating system, requires `inotifywait`(`inotify-tools`) to be installed. + MacOS alternative: `fswatch` ## Credentials - After deployment, when you go to localhost:5601, both username and password will be `admin` diff --git a/docker/filebeat/grant_container_logs_permissions.sh b/docker/filebeat/grant_container_logs_permissions.sh new file mode 100755 index 00000000..89eb7455 --- /dev/null +++ b/docker/filebeat/grant_container_logs_permissions.sh @@ -0,0 +1,8 @@ +#! /usr/bin/env bash + +while true +do + inotifywait /var/lib/docker/containers + sleep 1 + sudo chmod -R a+r /var/lib/docker/containers +done From c0297595735826045b319214a09c3b031659e9c4 Mon Sep 17 00:00:00 2001 From: Fu Zi Xiang Date: Mon, 6 Nov 2023 23:54:36 +0800 Subject: [PATCH 4/8] chore: merge with main --- ...d6290b7d73425f82bcf63ad4a0bd6959047d5.json | 14 --------- src/application.rs | 31 +++++++++++++------ 2 files changed, 21 insertions(+), 24 deletions(-) delete mode 100644 .sqlx/query-141454ccce32ab6abd9fba21292d6290b7d73425f82bcf63ad4a0bd6959047d5.json diff --git a/.sqlx/query-141454ccce32ab6abd9fba21292d6290b7d73425f82bcf63ad4a0bd6959047d5.json b/.sqlx/query-141454ccce32ab6abd9fba21292d6290b7d73425f82bcf63ad4a0bd6959047d5.json deleted file mode 100644 index 6c359972..00000000 --- a/.sqlx/query-141454ccce32ab6abd9fba21292d6290b7d73425f82bcf63ad4a0bd6959047d5.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": "141454ccce32ab6abd9fba21292d6290b7d73425f82bcf63ad4a0bd6959047d5" -} diff --git a/src/application.rs b/src/application.rs index fc973362..1c7ad25c 100644 --- a/src/application.rs +++ b/src/application.rs @@ -217,32 +217,43 @@ async fn setup_admin_account( match res_resp { Ok(resp) => match resp { - gotrue_entity::dto::SignUpResponse::Authenticated(_) => { - tracing::info!("Admin user already authenticated"); + gotrue_entity::dto::SignUpResponse::Authenticated(resp) => { + tracing::info!( + "Admin user already created and authenticated at {:?}", + resp.user.email_confirmed_at + ); Ok(()) }, gotrue_entity::dto::SignUpResponse::NotAuthenticated(user) => { let user_id = user.id.parse::().unwrap(); - sqlx::query!( + let result = sqlx::query( r#" UPDATE auth.users SET role = 'supabase_admin', email_confirmed_at = NOW() WHERE id = $1 "#, - user_id ) + .bind(user_id) .execute(pg_pool) .await .context("failed to update the admin user")?; + + assert_eq!(result.rows_affected(), 1); Ok(()) }, }, - Err(err) => match (err.code, err.msg.as_str()) { - (400, "User already registered") => { - tracing::info!("Admin user already registered"); - Ok(()) - }, - _ => Err(err.into()), + Err(err) => { + if let app_error::gotrue::GoTrueError::Internal(err) = err { + match (err.code, err.msg.as_str()) { + (400, "User already registered") => { + tracing::info!("Admin user already registered"); + Ok(()) + }, + _ => Err(err.into()), + } + } else { + Err(err.into()) + } }, } } From 17044ad4f0c2a8ea34b5757457a9c0947f496c84 Mon Sep 17 00:00:00 2001 From: Fu Zi Xiang Date: Tue, 7 Nov 2023 00:32:28 +0800 Subject: [PATCH 5/8] feat: indempotency restart for email autoconfirm and non autoconfirm --- libs/gotrue-entity/src/dto.rs | 2 +- src/application.rs | 62 ++++++++++++++++++++--------------- 2 files changed, 37 insertions(+), 27 deletions(-) diff --git a/libs/gotrue-entity/src/dto.rs b/libs/gotrue-entity/src/dto.rs index 319e0d96..89d9992f 100644 --- a/libs/gotrue-entity/src/dto.rs +++ b/libs/gotrue-entity/src/dto.rs @@ -197,7 +197,7 @@ impl OAuthProvider { pub struct OAuthURL { pub url: String, } -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Debug)] #[serde(untagged)] pub enum SignUpResponse { Authenticated(GotrueTokenResponse), diff --git a/src/application.rs b/src/application.rs index 1c7ad25c..a915611c 100644 --- a/src/application.rs +++ b/src/application.rs @@ -215,33 +215,9 @@ async fn setup_admin_account( let password = gotrue_setting.admin_password.as_str(); let res_resp = gotrue_client.sign_up(admin_email, password).await; - match res_resp { - Ok(resp) => match resp { - gotrue_entity::dto::SignUpResponse::Authenticated(resp) => { - tracing::info!( - "Admin user already created and authenticated at {:?}", - resp.user.email_confirmed_at - ); - Ok(()) - }, - gotrue_entity::dto::SignUpResponse::NotAuthenticated(user) => { - let user_id = user.id.parse::().unwrap(); - let result = sqlx::query( - r#" - UPDATE auth.users - SET role = 'supabase_admin', email_confirmed_at = NOW() - WHERE id = $1 - "#, - ) - .bind(user_id) - .execute(pg_pool) - .await - .context("failed to update the admin user")?; + println!("res_resp: {:?}", &res_resp); - assert_eq!(result.rows_affected(), 1); - Ok(()) - }, - }, + match res_resp { Err(err) => { if let app_error::gotrue::GoTrueError::Internal(err) = err { match (err.code, err.msg.as_str()) { @@ -255,6 +231,40 @@ async fn setup_admin_account( Err(err.into()) } }, + Ok(resp) => match resp { + gotrue_entity::dto::SignUpResponse::Authenticated(resp) => { + tracing::info!( + "Admin user already created and authenticated at {:?}", + resp.user.email_confirmed_at + ); + Ok(()) + }, + gotrue_entity::dto::SignUpResponse::NotAuthenticated(user) => match user.role.as_str() { + "supabase_admin" => { + tracing::info!("Admin user already created and set role to supabase_admin"); + Ok(()) + }, + _ => { + let user_id = user.id.parse::().unwrap(); + let result = sqlx::query( + r#" + UPDATE auth.users + SET role = 'supabase_admin', email_confirmed_at = NOW() + WHERE id = $1 + "#, + ) + .bind(user_id) + .execute(pg_pool) + .await + .context("failed to update the admin user")?; + + assert_eq!(result.rows_affected(), 1); + tracing::info!("Admin user created and set role to supabase_admin"); + + Ok(()) + }, + }, + }, } } From 32390676f19f2b35db8d9ae48a08ec7d4a49d0ff Mon Sep 17 00:00:00 2001 From: Fu Zi Xiang Date: Tue, 7 Nov 2023 01:17:08 +0800 Subject: [PATCH 6/8] fix: user not allowed --- dev.env | 2 +- doc/deployment.md | 1 + src/application.rs | 21 ++++++++++----------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/dev.env b/dev.env index c21673b6..6dcd3b16 100644 --- a/dev.env +++ b/dev.env @@ -8,7 +8,7 @@ GOTRUE_JWT_SECRET=hello456 # user sign up will automatically be confirmed if this is set to true # if you have OAuth2 set up or smtp configured, you can set this to false # to enforce email confirmation or OAuth2 login instead -GOTRUE_MAILER_AUTOCONFIRM=true +GOTRUE_MAILER_AUTOCONFIRM=false # if you enable mail confirmation, you need to set the SMTP configuration below GOTRUE_SMTP_HOST=smtp.gmail.com diff --git a/doc/deployment.md b/doc/deployment.md index eb9d55c1..10c62920 100644 --- a/doc/deployment.md +++ b/doc/deployment.md @@ -13,6 +13,7 @@ we recommend using cloud compute services (as your host server) such as ## Software Requirements - [docker compose](https://docs.docker.com/compose) This is needed be installed in your host server +- We recommend using approach as proposed by offical docker website: [Install Docker Engine](https://docs.docker.com/engine/install/) ## Steps diff --git a/src/application.rs b/src/application.rs index a915611c..7bb70de4 100644 --- a/src/application.rs +++ b/src/application.rs @@ -231,21 +231,20 @@ async fn setup_admin_account( Err(err.into()) } }, - Ok(resp) => match resp { - gotrue_entity::dto::SignUpResponse::Authenticated(resp) => { - tracing::info!( - "Admin user already created and authenticated at {:?}", - resp.user.email_confirmed_at - ); - Ok(()) - }, - gotrue_entity::dto::SignUpResponse::NotAuthenticated(user) => match user.role.as_str() { + 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" => { tracing::info!("Admin user already created and set role to supabase_admin"); Ok(()) }, _ => { - let user_id = user.id.parse::().unwrap(); + let user_id = admin_user.id.parse::().unwrap(); let result = sqlx::query( r#" UPDATE auth.users @@ -263,7 +262,7 @@ async fn setup_admin_account( Ok(()) }, - }, + } }, } } From d06f8d89b7cd698770744dc101c04ebc64b3183c Mon Sep 17 00:00:00 2001 From: Fu Zi Xiang Date: Tue, 7 Nov 2023 10:01:00 +0800 Subject: [PATCH 7/8] chore: remove unneeded print --- src/application.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/application.rs b/src/application.rs index 7bb70de4..cdf4d39d 100644 --- a/src/application.rs +++ b/src/application.rs @@ -214,9 +214,6 @@ async fn setup_admin_account( let admin_email = gotrue_setting.admin_email.as_str(); let password = gotrue_setting.admin_password.as_str(); let res_resp = gotrue_client.sign_up(admin_email, password).await; - - println!("res_resp: {:?}", &res_resp); - match res_resp { Err(err) => { if let app_error::gotrue::GoTrueError::Internal(err) = err { From 91bc8568aebfb3dd67dbd9f4082a3bc6f360e4e7 Mon Sep 17 00:00:00 2001 From: Fu Zi Xiang Date: Tue, 7 Nov 2023 11:00:37 +0800 Subject: [PATCH 8/8] fix: unwrap --- src/application.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/application.rs b/src/application.rs index cdf4d39d..c7639463 100644 --- a/src/application.rs +++ b/src/application.rs @@ -241,7 +241,7 @@ async fn setup_admin_account( Ok(()) }, _ => { - let user_id = admin_user.id.parse::().unwrap(); + let user_id = admin_user.id.parse::()?; let result = sqlx::query( r#" UPDATE auth.users