Helpers 

user model 

Gadget by default sets the email, firstName, lastName, googleImageUrl and roles fields within your user model.

Google OAuth Sign Up trigger 

This trigger executes when a new user signs up using Google OAuth. The entire profile payload from Google is included in the trigger.

Google OAuth Sign In trigger 

This trigger executes when when an existing user signs in using Google OAuth. The entire profile payload from Google is included in the trigger.

signUp action 

A user model's signUp action is a create action by default.

Its run function includes setting the lastSignedIn field of the user record to the current date and time. This indicates when the user last signed in or, in this context, when the user created their account.

In addition, it associates the current user record with the active session.

user/signUp.js
JavaScript
1import {
2 applyParams,
3 save,
4 ActionOptions,
5 SignUpUserActionContext,
6} from "gadget-server";
7
8/**
9 * @param { SignUpUserActionContext } context
10 */
11export async function run({ params, record, logger, api, session }) {
12 applyParams(params, record);
13 record.lastSignedIn = new Date();
14 await save(record);
15
16 // associate the current user record with the active session
17 session?.set("user", { _link: record.id });
18}
19
20/**
21 * @param { SignUpUserActionContext } context
22 */
23export async function onSuccess({ params, record, logger, api }) {
24 // Your logic goes here
25}
26
27/** @type { ActionOptions } */
28export const options = {
29 actionType: "create",
30};

signIn action 

A user model's signIn action is an update action by default.

It updates the lastSignedIn field of the user record to the current date and time and associates the current user record with the active session.

user/signIn.js
JavaScript
1import { save, ActionOptions, SignInUserActionContext } from "gadget-server";
2
3/**
4 * @param { SignInUserActionContext } context
5 */
6export async function run({ params, record, logger, api, session }) {
7 record.lastSignedIn = new Date();
8 await save(record);
9
10 // associate the current user record with the active session
11 session?.set("user", { _link: record.id });
12}
13
14/**
15 * @param { SignInUserActionContext } context
16 */
17export async function onSuccess({ params, record, logger, api }) {
18 // Your logic goes here
19}
20
21/** @type { ActionOptions } */
22export const options = {
23 actionType: "update",
24};

signOut action 

A user model's signOut action is an update action by default.

It unsets the associated user on the active session, causing the session to be unauthenticated.

user/signOut.js
JavaScript
1import { ActionOptions, SignOutUserActionContext } from "gadget-server";
2
3/**
4 * @param { SignOutUserActionContext } context
5 */
6export async function run({ params, record, logger, api, session }) {
7 // unset the associated user on the active session
8 session?.set("user", null);
9}
10
11/**
12 * @param { SignOutUserActionContext } context
13 */
14export async function onSuccess({ params, record, logger, api }) {
15 // Your logic goes here
16}
17
18/** @type { ActionOptions } */
19export const options = {
20 actionType: "update",
21};

Deleting the user model 

It's critical to the current authentication setup within your Gadget app that you don't delete the user model.

However if you happen to mistakenly delete the user model below are steps to re-summon the model to ensure you're able to properly setup your authentication flow.

  1. Add a model and name it user
  2. Add the email, firstName, lastName, googleImageUrl, roles and lastSignedIn default fields back to the user model.

When adding the lastSignedIn field ensure you select the Include time option

user fieldsField typeValidation/Default value
emailemailEmail address, Required (Validation)
firstNamestringN/A
lastNamestringN/A
emailVerfiedbooleanN/A
googleImageUrlurlURL (Validation)
googleProfileIdstringN/A
rolesrole listsigned-in (Default value)
lastSignedIndate / timeN/A
  1. Add the signUp, signIn and signOut actions to the user model
  2. Add the appropriate Google OAuth trigger to the signUp and signIn action, while also removing the default associated API trigger
  3. Copy the code files above of the corresponding actions added and paste them within the action code file
  4. Head to the Roles and Permissions (under Settings) and ensure the signed-in column within the user model is selected for read and signOut
  5. Finally go to the session model page and under its fields, click on the user relationship field (session belongs to Parent). Then head to the Parent input and from the dropdown select user. Finally, select the has one option so that user has one session. This will re-establish the relationship between the session record and the user model.
A screenshot of re-establishing the relationship of the user model and session record

Hooks and components 

When working with Gadget auth, there are several hooks and components from our @gadgetinc/react package that can help you manage the authentication state of your application.

The Provider component exported from this library accepts an auth prop which can be used to configure the relative paths to your app's sign in and sign out endpoints. If you do not provide these paths, the default values of /auth/signin and /auth/signout will be used.

The hooks use the Gadget client's suspense: true option, making it easier to manage the async nature of the hooks without having to deal with loading state.

use the Provider to set the signInPath and signOutActionApiIdentfier
tsx
1import { Client } from "@gadget-client/my-gadget-app";
2import { Provider } from "@gadgetinc/react";
3import { Suspense } from "react";
4import App from "./App";
5
6// instantiate the API client for our app
7const api = new Client({ authenticationMode: { browserSession: true } });
8
9export function main() {
10 // ensure any components which use the @gadgetinc/react hooks are wrapped with the Provider and a Suspense component
11 return (
12 <Provider api={api} auth={{ signInPath: "/auth/signin", signOutActionApiIdentifier: "signOut" }}>
13 <Suspense fallback={<>Loading...</>}>
14 <App />
15 </Suspense>
16 </Provider>
17 );
18}
HooksDescription
useSession()Retrieves the current user session within the app.
useUser()If a user is present in the session, it returns the current user; otherwise, it returns null for unauthenticated sessions.
useAuth()Returns an object representing the current authentication state of the session.
useSignOut()Returns a callback that you can call to sign out your current Gadget User from the current Session. This calls the configured signOutActionApiIdentifier action, which is the User signOut action by default.
ComponentsDescription
<SignedIn />Conditionally renders its children if the current session has a user associated with it, similar to the isSignedIn property of the useAuth() hook.
<SignedOut />Conditionally renders its children if the current session does not have a user associated with it.
<SignedInOrRedirect />Conditionally renders its children based on the user's sign-in status. If a user is currently signed in, it displays its children; otherwise, it redirects the browser using window.location.assign. This functionality is valuable for securing front-end routes.
<SignedOutOrRedirect />Conditionally renders its children when there is no user associated with the current session. However, if the user is signed in, it redirects the browser using window.location.assign. Its purpose is to facilitate redirection of front-end routes based on the user's sign-in status.