Extend the User Object

Learn how to add custom fields and metadata to the user profile using JopiJS's interface merging system.

Overview

Every application has unique requirements for user data. While JopiJS provides a standard set of fields (id, email, roles), you will likely need to add custom metadata like a birth date, phone number, or preferences.

In JopiJS, this is achieved through Interface Merging. Because the user object is shared via a virtual path, any module can contribute new fields to the global IUserInfos type without breaking existing code.


1. The Core Interface

The standard user object is defined by a base interface shared at the path @/lib/jopijs.auth.IUserInfos. By default, JopiJS provides the following structure:

Default Interface Definition
interface IUserInfos {
    id: string;

    roles?: string[];
    email?: string;

    fullName?: string;
    nickName?: string;

    firstName?: string;
    lastName?: string;

    avatarUrl?: string;

    [key: string]: any; // Allows for dynamic extensibility
}

Field Descriptions

FieldTypeOptional?Description
idstringNoThe unique identifier for the user.
rolesstring[]YesA list of roles assigned to the user (e.g., ["admin"]).
emailstringYesThe user's email address.
fullNamestringYesThe complete name (e.g., "John Doe").
nickNamestringYesA shorter public name or handle.
firstNamestringYesThe user's first name.
lastNamestringYesThe user's family name.
avatarUrlstringYesURL to the user's profile picture.
[key: string]anyYesCatch-all for any other custom metadata.

2. Adding Custom Fields

To add fields, you must create a new module that "merges" its own definition into the core interface.

Step A: Folder Structure

Create the following structure in your custom module. The interface.merge file is the key marker here.

Project Organization
src/ mod_custom_profile/
└── @alias/lib/jopijs.auth.IUserInfos/
    ├── index.ts
    ├── interface.merge   # <--- Tells JopiJS to MERGE definitions
    └── high.priority     # Recommended to ensure availability

Step B: The Definition

In your index.ts, update the IUserInfos interface with your new fields. JopiJS will automatically combine this with the original version.

src/mod_custom_profile/@alias/lib/jopijs.auth.IUserInfos/index.ts
export default interface IUserInfos {
    phoneNumber?: string;
    birthDate_year?: number;
    birthDate_month?: number;
    birthDate_day?: number;
    preferences?: {
        darkMode: boolean;
        newsletter: boolean;
    };
}

3. Populating the Data

Once the type is extended, you need to ensure your data source (JSON file or Database) actually provides these fields.

If using JSON (Default)

Override the shared user list with your own version containing the new fields.

src/mod_custom_profile/@alias/res/jopijs.auth.userList/
├── index.ts
├── high.priority      # Force JopiJS to use THIS list
└── user.gen.json
user.gen.json
[
  {
    "authInfos": { "login": "admin", "password": "admin" },
    "userInfos": {
      "id": "admin",
      "roles": ["admin", "bigboss"],
      "fullName": "The Admin",
      "phoneNumber": "+33 6 00 00 00 00",
      "birthDate_year": 1990
    }
  }
]

If using a Database

Simply update your findUser override to return the new fields from your database query.
See the Backend Logic section in the Authentication guide for more details.


4. Using the Data in UI

To access these fields in your React components, use the useGetInfos hook. Thanks to TypeScript and JopiJS's merging, you will get full auto-completion for your custom fields!

src/mod_ui/UserProfile.tsx
import useGetInfos from "@/hooks/jopijs.user.useGetInfos";

export default function UserProfile() {
    const user = useGetInfos();

    if (!user) return null;

    return (
        <div>
            <h1>Hello, {user.fullName}</h1>
            <p>Birth Year: {user.birthDate_year}</p>
            <p>Phone: {user.phoneNumber}</p>
        </div>
    );
}

Internal Shortcut: The hook @/hooks/jopijs.user.useGetInfos is provided by the @jopijs/jopimod_uicore module, which is a core dependency of the authentication system.


Summary

  1. Define: Create a folder @alias/lib/jopijs.auth.IUserInfos/ in your module.
  2. Marker: Add an empty interface.merge file.
  3. Code: Export a default interface with your new fields.
  4. Data: Update your user provider (JSON or DB) to include the values.
  5. Enjoy: Use the data anywhere with full TypeScript support.