-
-
Save koakh/fbbc37cde630bedcf57acfd4d6a6956b to your computer and use it in GitHub Desktop.
| **As a developer you have complete control over the signup and signin functionality...** | |
| ```shell | |
| $ surreal sql --conn http://localhost:8000 --user root --pass root --ns test --db test | |
| ``` | |
| ```sql | |
| -- optional : this is the default see --ns test --db test start server flags | |
| -- USE NS test DB test; | |
| -- define TABLE user SCHEMAFULL PERMISSIONS FOR select, update WHERE id = $auth.id FOR create, delete NONE; // miss , | |
| -- Tobie: However, make it schemaless, as you haven't defined fields. | |
| -- SCHEMAFULL if we defined fields else use SCHEMALESS | |
| ---opt1:SCHEMALESS | |
| -- DEFINE TABLE user SCHEMALESS | |
| -- PERMISSIONS | |
| -- FOR select, update WHERE id = $auth.id, | |
| -- FOR create, delete NONE; | |
| -- warn with opt1 if we re signup again it will create another user with same email, and after it all signin's will fail, | |
| -- to fix this issue always use next opt2 that have a UNIQUE INDEX, and prevents create a user with same email, and this is the expected behavior | |
| ---opt2:SCHEMAFULL | |
| DEFINE TABLE user SCHEMAFULL | |
| PERMISSIONS | |
| FOR select, update WHERE id = $auth.id, | |
| FOR create, delete NONE; | |
| DEFINE FIELD user ON user TYPE string; | |
| DEFINE FIELD pass ON user TYPE string; | |
| DEFINE FIELD settings.* ON user TYPE object; | |
| DEFINE FIELD settings.marketing ON user TYPE string; | |
| DEFINE FIELD tags ON user TYPE array; | |
| DEFINE INDEX idx_user ON user COLUMNS user UNIQUE; | |
| -- define scope | |
| DEFINE SCOPE allusers | |
| -- the JWT session will be valid for 14 days | |
| SESSION 14d | |
| -- The optional SIGNUP clause will be run when calling the signup method for this scope | |
| -- It is designed to create or add a new record to the database. | |
| -- If set, it needs to return a record or a record id | |
| -- The variables can be passed in to the signin method | |
| SIGNUP ( CREATE user SET settings.marketing = $marketing, user = $user, pass = crypto::argon2::generate($pass), tags = $tags ) | |
| -- The optional SIGNIN clause will be run when calling the signin method for this scope | |
| -- It is designed to check if a record exists in the database. | |
| -- If set, it needs to return a record or a record id | |
| -- The variables can be passed in to the signin method | |
| SIGNIN ( SELECT * FROM user WHERE user = $user AND crypto::argon2::compare(pass, $pass) ) | |
| -- this optional clause will be run when calling the signup method for this scope | |
| ``` | |
| ctrl+c | |
| check info db in shell | |
| ```shell | |
| $ echo "INFO FOR DB;" | surreal sql --conn http://localhost:8000 --user root --pass root --ns test --db test | jq | |
| ``` | |
| check info db in REPL | |
| ```shell | |
| $ surreal sql --conn http://localhost:8000 --user root --pass root --ns test --db test --pretty | |
| ``` | |
| ```sql | |
| INFO FOR DB; | |
| ``` | |
| ```json | |
| [ | |
| { | |
| "time": "249.753µs", | |
| "status": "OK", | |
| "result": { | |
| "dl": {}, | |
| "dt": {}, | |
| "sc": { | |
| "allusers": "DEFINE SCOPE allusers SESSION 2w SIGNUP (CREATE user SET settings.marketing = $marketing, email = $email, pass = crypto::argon2::generate($pass), tags = $tags) SIGNIN (SELECT * FROM user WHERE email = $email AND crypto::argon2::compare(pass, $pass))" | |
| }, | |
| "tb": { | |
| "user": "DEFINE TABLE user SCHEMALESS PERMISSIONS FOR select WHERE id = $auth.id, FOR create NONE, FOR update WHERE id = $auth.id, FOR delete NONE" | |
| } | |
| } | |
| } | |
| ] | |
| ``` | |
| Then you could use the **following query from the client to signup (create) a new user**, or **signin (select) an existing user**... | |
| ```js | |
| db.signup({ | |
| NS: 'my_ns', | |
| DB: 'my_db', | |
| SC: 'allusers', // We want to signup to the 'allusers' scope defined above | |
| email: '[email protected]', // We can add any variable here to use in the SIGNUP clause | |
| pass: 'some password', // We can add any variable here to use in the SIGNUP clause | |
| marketing: true, // We can add any variable here to use in the SIGNUP clause | |
| tags: ['rust', 'golang', 'javascript'], // We can add any variable here to use in the SIGNUP clause | |
| }); | |
| // you should receive a jwt token | |
| db.signin({ | |
| NS: 'my_ns', | |
| DB: 'my_db', | |
| SC: 'allusers', // We want to signup to the 'allusers' scope defined above | |
| email: '[email protected]', // We can add any variable here to use in the SIGNUP clause | |
| pass: 'some password', // We can add any variable here to use in the SIGNUP clause | |
| }); | |
| // you should receive a jwt token | |
| ``` |
@koakh hi, can you help us with argon2 https://github.com/orgs/surrealdb/discussions/2196#discussioncomment-6314556
Thanks for the great guidance
I am using the signup function and providing a username and password. After that I use the signin function with the same username but with the a different password, I was expecting an error but I still got a token also calling the authenticate function after that did not throw an error. How is this possible? What am I doing wrong?
await db.signup({
NS: "mydb",
DB: "mydb",
SC: "allusers",
user: "jane",
password: "jane",
email: "[email protected]",
});
const token = await db.signin({
NS: "mydb",
DB: "mydb",
SC: "allusers",
user: "jane",
password: "jane1",
});
await db.authenticate(token)
All of this still works even though I give an incorrect pass while signin
@dustsucker did you ever get dynamic namespace/database creation working? I also need to create a namespace/database for each new user logging into the system. It seems like a trivial exercise but I can't seem to find a clear solution to this. Basically, a login flow like Supabase. Login -> Create a Project (new namespace/db in our case) and you're in. Extra bonus points for building a connection string so people can access SDB from the net.