surrealdb / surrealdb.js

SurrealDB SDK for JavaScript
https://surrealdb.com
Apache License 2.0
300 stars 48 forks source link

Bug: authenticate() can only be used with scopes. #180

Closed irishburlybear closed 9 months ago

irishburlybear commented 1 year ago

Describe the bug

DB / NS users fail with the token that's been given back after signing in. If it's a scoped user. It's fine.

Steps to reproduce

await.signin(
{ 
NS: 'test',
DB: 'testdb',
user: 'admin',
pass: 'admin',
)

//Get a token back : (notice no scope... This isn't a scoped user..)

Dissect token:  {
  iat: 1698420036,
  nbf: 1698420036,
  exp: 1698423636,
  iss: 'SurrealDB',
  NS: 'test',
  DB: 'testdb',
  ID: 'admin'

// try to re authenticate through sveltekit hooks.server.js:
const session = event.cookies.get('token')
if(session){
await db.authenticate(session)
}

Error: There was a problem with authentication at WebSocketStrategy.authenticate (file:///home/administrator/sis/node_modules/surrealdb.js/esm/strategies/websocket.js:195:19) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async Object.handle (/home/administrator/sis/src/hooks.server.js:25:13) at async Module.respond (/home/administrator/sis/node_modules/@sveltejs/kit/src/runtime/server/respond.js:282:20) at async file:///home/administrator/sis/node_modules/@sveltejs/kit/src/exports/vite/dev/index.js:510:22

Expected behaviour

Should just authenticate the user, as the owner /editor / viewer of Database or Namespace..

SurrealDB version

surreal 1.0.0

SurrealDB.js version

0.9.1

Contact Details

irishburlybear@gmail.com

Is there an existing issue for this?

Code of Conduct

irishburlybear commented 1 year ago

My thinking with DB or NS users: they are the SUPER users of the app I'm developing and should have access to all of the db(s) of the namespace.

kearfy commented 1 year ago

Heya @irishburlybear, I'm not sure why authentication is failing for here. As you can see in #182, this behaviour is supported just fine.

Happy to debug with you to find the cause of your problem! 😃

irishburlybear commented 1 year ago

Should I test on the new v .10 ?

Are you sure that what you pass to the function (since you retrieve it from cookies) is actually a token?: Oh yes. I did. I ripped open that token to see the contents and I thought it aligned well. (NS, DB, SC etc..)

Could you check if enabling trace logging (--log trace) for your surrealdb instance reveals any interesting information!: Yes, I can.

Do the selected namespace/database match the ones in the authentication token?: I believe so. I was searching over the source for maybe a mis spelling or something.

Let me gather more data.

kearfy commented 1 year ago

Awesome thanks! You can, though it should not make a difference

irishburlybear commented 1 year ago

Ok, So what I'm getting back: (v.10) I'm authenticating! The token is being read correctly now! I'm using this at the top of the script:

await db.use({namespace:'sis', database:'district'})

But I'm getting this:

Error: There was a problem with the database: Specify a database to use.

But I did specify the database??

Here is the token after logging in with JUST Namespace: (There is no DB. I'm guessing use database should of have put that in there? Or is that coming from signin() ?)

Dissect token: { iat: 1698667621, nbf: 1698667621, exp: 1698671221, iss: 'SurrealDB', NS: 'sis', ID: 'sis' }

irishburlybear commented 1 year ago

Here is my little work around: hooks.server.js:

 const token = JSON.parse(Buffer.from(session.split('.')[1], 'base64').toString())

            await db.connect(DB_URL)
            if(!token.DB){
                //no database assign one:
                await db.use({namespace:'sis',database: 'district'})
            }

I'm thinking this might be the correct way to do this? I think I might need to setup a way for the super users to get assigned a home DB then have the ability to change once logged in.

kearfy commented 1 year ago

Could you send your full script, from initiating the client to the authentication call?

irishburlybear commented 1 year ago
import { z } from 'zod'
import { fail } from '@sveltejs/kit'
import { Surreal } from 'surrealdb.js'
import { DB_URL } from '$env/static/private'

const db = new Surreal()
await db.connect(DB_URL)
await db.use({database:'district', namespace:'sis'})

export let actions = {
    login: async ({ request, cookies }) => {
        const data = Object.fromEntries(await request.formData())
        console.log(data)

        const login_schema = z.object({
            user: z.string().min(1, `Username blank!`),
            pass: z.string().min(1, `Password blank!`)
        })

        try {
            login_schema.parse(data)
        } catch (err) {
            if (err instanceof z.ZodError) {
                return fail(400, err.issues)
            }
        }

        try {

            const token = await db.signin({
                namespace: 'sis',
                username: data.user,
                password: data.pass
            })

            console.log(token)

            cookies.set('token', token, {
                path: '/',
                httpOnly: true,
                sameSite: 'lax',
                secure: process.env.NODE_ENV === 'production',
                maxAge: 60 * 60 * 3
            })

            return

        } catch (err) {
            console.log(err)
            return fail(400, [{
                message: 'Wrong credentials!',
                path: ['general']
            }])
        }
    }
}
irishburlybear commented 9 months ago

This works now. Thank you!