DEV Community

Discussion on: Create A Serverless School Management System with React, Auth0 and FaunaDB

Collapse
 
dominwong4 profile image
dominwong4 • Edited

Hi, great tutorial.
But it is only for pre-generated user
so I add below code to create user if no record inside fauna db
would you mind to see if it is good or not?

try {
  user_from_fauna = await client.query(
    q.Get(q.Match(q.Index("users_by_email"), user.email))
  );
} catch (error) {
  throw new Error("No user with this email exists");
} finally{
  //create user if no user with this email
  if (!user_from_fauna){
    user_from_fauna = await client.query(
        q.Create(q.Collection("Users"),{data:{email:user.email}}
    ));
  } more code below......
Enter fullscreen mode Exit fullscreen mode
Collapse
 
drejohnson profile image
DeAndre Johnson

This way checks for the existence of user and creates a user if it doesn't exist. This could be simplified even further. Checking if user exist, creating new user if it doesn't, creating token and returning user instance could all be done in a single query. FQL is a very powerful query language.

async function faunaUserAuth(user, context, callback) {
  const { Client, query: q } = require("faunadb@2.11.1"); // from Auth0 registry. See https://auth0.com/docs/rules

  const client = new Client({
    secret: configuration.SERVER_SECRET,
  });

  try {
    let user_from_fauna = await client.query(
      q.Let(
        {
          "userExists": q.Exists(
            q.Match(q.Index("user_by_email"), user.email)
          ),
        },
        q.If(
          q.Not(Var("userExists")),
          q.Create(q.Collection("Users"),{data:{email:user.email}}),
          q.Get(q.Match(q.Index("user_by_email"), user.email))
        )
      )
    );

    /* create a secret from the user's ref in the Tokens collection */
    const credential = await client.query(
      q.Create(q.Tokens(), { instance: user_from_fauna.ref })
    );

    user.user_metadata = {
      secret: credential.secret,
      user_id: credential.instance.id,
      role: user_from_fauna.ref.collection.id.toLowerCase().slice(0, -1),
    };

    /* The custom claim allows us to attach the user_metadata to the returned object */
    const namespace = "https://fauna.com/"; // fauna because we are using FaunaDB
    context.idToken[namespace + "user_metadata"] = user.user_metadata;

    await auth0.users
      .updateUserMetadata(user.user_id, user.user_metadata);

    callback(null, user, context);
  } catch (error) {
    callback(error, user, context);
  }
}
Enter fullscreen mode Exit fullscreen mode