Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Darkle/a84a9a126ac6bd3eff635355ac54548f to your computer and use it in GitHub Desktop.
Save Darkle/a84a9a126ac6bd3eff635355ac54548f to your computer and use it in GitHub Desktop.
SurrealDB : How to use signin and signup (server + client nodesjs)

As a developer you have complete control over the signup and signin functionality...

$ surreal sql --conn http://localhost:8000 --user root --pass root --ns test --db test
-- 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

$ echo "INFO FOR DB;" | surreal sql --conn http://localhost:8000 --user root --pass root --ns test --db test | jq

check info db in REPL

$ surreal sql --conn http://localhost:8000 --user root --pass root --ns test --db test --pretty
INFO FOR DB;
[
  {
    "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...

db.signup({
  NS: 'my_ns',
  DB: 'my_db',
  SC: 'allusers', // We want to signup to the 'allusers' scope defined above
  email: 'test@acme.com', // 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: 'test@acme.com', // 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment