-
-
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.