teodevgroup / teo

Schema-driven web server framework.
https://teodev.io
Apache License 2.0
1.33k stars 43 forks source link

Bug: virtual fields are created when creating table #59

Closed akelyasir closed 2 months ago

akelyasir commented 2 months ago

Hi @victorteokw

I was reviewing the documents you prepared, but I'm getting an error at one point. I get errors in the codes at this address "https://docs.teodev.io/getting-started/beginner-tutorial/implement-authentication#phone-number-and-auth-code".

When I first run the code I don't get any errors. But when I restart the system it gives an error.

db provider postgresql

schema.teo

connector {
  provider: .postgres,
  url: "postgres://user:password@localhost:5432/deneme"
}

server {
  bind: ("0.0.0.0", 5052)
}

entity {
  provider: .rust,
  dest: "./src/entities"
}

declare pipeline item validateAuthCode<T>: T -> String

@identity.tokenIssuer($identity.jwt(expired: $get(.expired).presents))
@identity.jwtSecret(ENV["JWT_SECRET"]!)
@identity.validateAccount(
  $message($get(.enabled).presents.eq(true), "this account is blocked"))
model User {
  @id @autoIncrement @readonly
  id: Int
  @unique @onSet($if($presents, $isEmail)) @identity.id
  @presentWithout(.phoneNumber)
  email: String?
  @writeonly @onSet($presents.bcrypt.salt)
  @identity.checker(
    $do($get(.value).presents.bcrypt.verify($self.get(.password).presents))
    .do($get(.companions).presents.get(.imageAuthToken).presents))
  password: String?
  @virtual @writeonly @identity.companion
  imageAuthToken: String?
  @virtual @writeonly @identity.companion
  expired: Int64?
  @migration(default: true) @default(true)
  enabled: Bool
  @identity.id @unique
  thirdPartyId: String?
  @virtual @writeonly @identity.checker($get(.value).presents.valid)
  thirdPartyToken: String?
  @onSet($if($presents, $regexMatch(/\\+?[0-9]+/))) @identity.id
  @presentWithout(.email) @unique
  phoneNumber: String?
  @virtual @writeonly @identity.checker($validateAuthCode)
  authCode: String?

  include handler identity.signIn
  include handler identity.identity
}

model AuthCode {
  @id @autoIncrement @readonly
  id: Int
  @presentWithout(.phoneNumber) @unique
  email: String?
  @presentWithout(.email) @unique
  phoneNumber: String?
  @onSave($randomDigits(4))
  code: String
}

middlewares [identity.identityFromJwt(secret: ENV["JWT_SECRET"]!)]

main.rs

pub mod entities;

use entities::{Teo, User};
use indexmap::indexmap;
use tokio::main;
use teo::prelude::{pipeline::item::validator::Validity, App, Result, Value, Error};

#[main]
async fn main() -> Result<()> {
    let app = App::new()?;
    app.main_namespace_mut().define_validator_pipeline_item("validateAuthCode", move |check_args: Value, user: User, teo: Teo| async move {
        let mut finder = Value::Dictionary(indexmap!{});
        let check_args = check_args.as_dictionary().unwrap();
        let ids = check_args.get("ids").unwrap().as_dictionary().unwrap();
        if ids.contains_key("email") {
            finder.as_dictionary_mut().unwrap().insert("email".to_owned(), ids.get("email").unwrap().clone());
        }
        if ids.contains_key("phoneNumber") {
            finder.as_dictionary_mut().unwrap().insert("phoneNumber".to_owned(), ids.get("phoneNumber").unwrap().clone());
        }
        let auth_code = teo.auth_code().find_unique(finder).await?;
        match auth_code {
            Some(auth_code) => if auth_code.code().as_str() == check_args.get("value").unwrap().as_str().unwrap() {
                Ok::<Validity, Error>(Validity::Valid)
            } else {
                Ok(Validity::Invalid("auth code is wrong".to_owned()))
            },
            None => Ok(Validity::Invalid("auth code not found".to_owned()))
        }
    });
    app.run().await
}

Error

thread 'main' panicked at /home/yakel/.cargo/registry/src/index.crates.io-6f17d22bba15001f/teo-sql-connector-0.2.28/src/migration/migrate.rs:237:71:
called `Result::unwrap()` on an `Err` value: Error { kind: QueryError(Error { kind: Db, cause: Some(DbError { severity: "ERROR", parsed_severity: Some(Error), code: SqlState(E42601), message: "syntax error at or near \"`\"", detail: None, hint: None, position: Some(Original(13)), where_: None, schema: None, table: None, column: None, datatype: None, constraint: None, file: Some("scan.l"), line: Some(1176), routine: Some("scanner_yyerror") }) }), original_code: Some("42601"), original_message: Some("db error: ERROR: syntax error at or near \"`\"") }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
akelyasir commented 2 months ago

@victorteokw

I think I found the problem. It doesn't give an error when @virtual is not present. But I don't know how to fix this

victorteokw commented 2 months ago

Hi @akelyasir, I will look into this.

victorteokw commented 2 months ago

It looks like SQL building bug. If it's confirmed to be a bug. I will publish a new version today.

victorteokw commented 2 months ago

Hi @akelyasir, are you using Teo 0.2.30?

victorteokw commented 2 months ago

@akelyasir, I reproduced this bug. I'll fix and publish a new version soon.

victorteokw commented 2 months ago

Hi @akelyasir, Teo 0.2.31 is published for Rust. Node.js and Python soon after GitHub CI is finished.