UDF Login function return 'Unauthorized'

I’m trying to call a pretty simple function, based on a login function found in the fwitter demo

{
  name: "auth_user_login",
  role: "admin",
  body: Query(
    Lambda(
      ["input"],
      Let(
        {
          account: Login(
            Match(Index("accounts_by_email"), Select("email", Var("input"))),
            { password: Select("password", Var("input")) }
          ),
          user: Get(Select(["data", "user"], Var("account"))),
          secret: Select(["secret"], Var("account"))
        },
        { account: Var("account"), user: Var("user"), secret: Var("secret") }
      )
    )
  )
}

and I’m getting a 401 / unauthorized response. I thought this meant my roles weren’t setup but testing with both my front end and the udf on admin privileges, still returns unauthorized. Could someone explain this error to me better? btw I have other UDF’s I’m able to call Thanks!

Unauthorized {name: "Unauthorized", message: "unauthorized", requestResult: RequestResult}
message: "unauthorized"
name: "Unauthorized"
requestResult: RequestResult
endTime: 1592447245808
method: "POST"
path: ""
query: null
requestContent: Expr {raw: {…}}
requestRaw: "{"call":{"function":"auth_user_login"},"arguments":{"object":{"email":"tatimblin@gmail.com","password":"TESTTEST"}}}"
responseContent: {errors: Array(1)}
responseHeaders: {content-length: "65", content-type: "application/json;charset=utf-8", x-txn-time: "1592447245679458"}
responseRaw: "{"errors":[{"code":"unauthorized","description":"Unauthorized"}]}"
startTime: 1592447245753
statusCode: 401
timeTaken: (...)
__proto__: Object
__proto__: FaunaHTTPError

Seems like it’s really the function that you can’t access.
I can’t see what is going wrong on first sight :confused:

Could it be possible you replaced the function? Removed it completely and added it again with the same name? A role might still have the reference to the old function in that case.

  • What driver are you using?
  • What role did you assign to the function?
  • You said you are trying to call the function with admin keys and even that is not working, is that correct?

Thanks for taking a look! I definitely recreated things a bunch while getting introduced to fauna. I will try again with a fresh name

1 Like

Hey was out of town and away from the computer, but I really appreciate your response.
Recreating the UDF with a new name did not resolve the issue. To answer your bullets

  • I am using the faunadb node module v2.11.1
  • The function (and the new one I just made) have a role of admin
  • I did switch to admin keys to try and debug

A little more insight the functions are setup as a stripped down version of what you did for fwitter. I’m able to call this

function userByAccount(client, email) {
  return client.query(Call(q.Function('user_by_account'), email)).then(res => res);
}

but not the very similar

function loginUser(client, email, password) {
  const input = {
    email,
    password,
  };
  return client.query(Call(q.Function('auth_account_login'), input)).then(res => flattenDataKeys(res));
}

they’re then also imported to query-manager.js and called on the front-end similarly

  login(email, password) {
    return loginUser(this.client, email, password).then((res) => {
      if (res) {
        this.client = new faunadb.Client({ secret: res.secret });
      }
      return res;
    });
  }
faunaQueries
  .login(this.email, this.password)
  .then((res) => {
    console.log(res);
  })
  .catch((err) => {
    console.error(err);
  });

and

  userByAccount(email) {
    return userByAccount(this.client, email).then((res) => {
      if (res) {
        this.client = new faunadb.Client({ secret: res.secret });
      }
      return res;
    });
  }
faunaQueries
  .userByAccount(this.email)
    .then((res) => {
      // Email was associated with a user
      this.user = res.data;

      this.page = this.page + 1;
      this.emailError = '';
      this.$emit('paginate', 'Submit');
    })
    .catch((err) => {
       // No user found with that email
       this.emailError = 'No user found with that email';
       console.log('User not found', err);
     });

Is there any other information I could provide?

Yeah I think that the two UDF function definitions would help a lot.
If you are able to prepare a small repository that reproduces this that would be great.
Since at this point I honestly have no idea how to help you further. It seems as if you bumped into a bug so I’d love to confirm whether that is the case or not.

@tatimblin are you sure you’re using an admin token?

What if you remove the role from the function itself and just assign privileges through custom roles?

Hey @databrecht I setup a demo for you here

Can I email you an api key?

Thanks for your response @pier! I got a little help in the slack channel before moving here, my custom role wasn’t working so I just switched it to the generic admin to make sure it wasn’t how I set those up.

Let’s connect over slack and jump on a quick call, since I’m still missing the actual definitions of the function and roles.

Thanks again for your assistance Brecht!
To summarize what my issue was, I had copied the query manager from the Fwitter example

  userByAccount(email) {
    return userByAccount(this.client, email).then((res) => {
      if (res) {
        this.client = new faunadb.Client({ secret: res.secret });  // <-- error
      }
      return res;
    });
  }

which logs the user in and replaces the default token with the one returned from Identity(), but my UDF doesn’t return the secret the same way. So when I did { secret: res.secret } I was really removing my admin keys, meaning subsequent calls had no token. Not updating the secret was all I needed to do.

1 Like