How to logout by ref

I need something like q.Logout(Ref) to invalidate all tokens for Ref.
How to solve this?
In documentation i see only solution based on tokens index and deleting tokens for instance or create client instance for Ref using theirs password and login and then q.Logout(true).
It’s looks very strange, a want q.Logout(q.Ref())

I mean, the whole point of this system is to track logins by their tokens. The functionality is there, you just need to do a bit of extra work to log everyone out using their Tokens. What exactly is the problem?

You’re not providing a whole lot of information: how do you login? do you create tokens yourself? etc etc.

With that being said, here’s one approach (you can follow the exact steps in the shell):

// 1. create a collection

// input
CreateCollection({ name: 'accounts' })

// output
{
  ref: Collection("accounts"),
  ts: 1649013429460000,
  history_days: 30,
  name: "accounts"
}

// 2. create index 'tokens_by_instance'

// input
CreateIndex({
  name: 'tokens_by_instance',
  source: Tokens(),
  terms: [
    { field: ['instance'] }  
  ]
})

// output
{
  ref: Index("tokens_by_instance"),
  ts: 1649014098020000,
  active: true,
  serialized: true,
  name: "tokens_by_instance",
  source: Ref("tokens"),
  terms: [
    {
      field: ["instance"]
    }
  ],
  partitions: 1
}

// 3. create a user in the said collection

// input
Create(Collection('accounts'), {
  data: { email: 'foo@bar.biz' },
  credentials: { password: 'foobar' }
})

// output
{
  ref: Ref(Collection("accounts"), "327947113472197193"),
  ts: 1649013589273000,
  data: {
    email: "foo@bar.biz"
  }
}

// 4. login. creates a token

// input
Login(Ref(Collection('accounts'), '327947113472197193'), {
  password: 'foobar'
})

// output
{
  ref: Ref(Ref("tokens"), "327947435310580297"),
  ts: 1649013896190000,
  instance: Ref(Collection("accounts"), "327947113472197193"),
  secret: "fnEEjRp0crACSQSNGeY1MAZJDQlVLJHwdSiM-ecksgu_yXZfLUs"
}



// 5. get the Ref of a token associated with the specific account Ref

// input
Get(Match(Index("tokens_by_instance"), Ref(Collection("accounts"), "327947113472197193")))

// output
{
  ref: Ref(Ref("tokens"), "327947435310580297"),
  ts: 1649013896190000,
  instance: Ref(Collection("accounts"), "327947113472197193"),
  hashed_secret: "$2a$05$bTdobx9W8s2IVf7URZioOuGBjE00UTGhou3xMf2xW7Y6OeO8ZIxay"
}

// delete the token to logout
// NOTE: this only deletes ONE token. if step 5 returned references to more than one - and you want to delete all of them - use Foreach function

// input
Delete(Ref(Ref("tokens"), "327947435310580297"))

// output
{
  ref: Ref(Ref("tokens"), "327947435310580297"),
  ts: 1649013896190000,
  instance: Ref(Collection("accounts"), "327947113472197193"),
  hashed_secret: "$2a$05$bTdobx9W8s2IVf7URZioOuGBjE00UTGhou3xMf2xW7Y6OeO8ZIxay"
}

// you can verify that the token is gone with the query from step 5:

// input
Get(Match(Index("tokens_by_instance"), Ref(Collection("accounts"), "327947113472197193")))

// output
Error: [
  {
    "position": [],
    "code": "instance not found",
    "description": "Set not found."
  }
]

To have more control over the tokens have a look at how you can manage it yourself. And here is additional info about refresh tokens.

1 Like

Exactly the problem in that looks like solution proposed by @boojum is the only one possible way to invalidate all tokens for ref, and this is very sad.

The Logout function is for identities that are requesting a logout. When the boolean parameter is true, all tokens associated with the identity are invalidated.

Your use case appears to be “The administrator wants to invalidate a specific identity’s tokens”. You can do that with @boojum 's answer, plus an additional query to remove all matching tokens:

Map(
  Paginate(
    Match(
      Index("tokens_by_instance"),
      Ref(Collection("accounts"), "327947113472197193"),
    ),
    { size: 100000 }
  ),
  Lambda("ref", Delete(Var("ref")))
)

This query removes all of the tokens (up to 100,000 at a time) that might be associated with a specific identity. You might need this form of query if the specified identity has logged in with multiple browsers, or has used a script to generate tokens in bulk.

and this is very sad

You are welcome to post a feature request. It would be helpful to describe the use case you need to solve, and perhaps what the solution might look like.

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.