X Enterprises
fastify-xauth-local

local.register

Built-in POST route that creates a new user account with a hashed password and returns a signed JWT.

local.register

Built-in POST {loginPath}/register route registered when local.enabled is true. Checks that no account with the given email exists, hashes the password with bcrypt, calls createUser, then returns a signed JWT.

Default path: {prefix}/local/register (e.g. /api/local/register)

Signature

POST {loginPath}/register
Content-Type: application/json

{
  "email": string,       // required, valid email format
  "password": string,    // required, minimum 8 characters
  "first_name": string,  // required, minimum 1 character
  "last_name": string    // required, minimum 1 character
}

Params

NameTypeRequiredDescription
emailstringYesNew user's email address
passwordstringYesPlaintext password (min 8 chars); hashed before storage
first_namestringYesGiven name
last_namestringYesFamily name

Returns

201 Created:

{
  "token": "eyJ...",
  "user": {
    "id": 1,
    "email": "user@example.com",
    "first_name": "Jane",
    "last_name": "Doe"
  }
}

Throws

StatusMessageReason
409An account with this email already existsDuplicate email check via userLookup
500An error occurred during registrationUnexpected server error

This route is automatically excluded from JWT verification so it can be accessed without a token.

Examples

Basic: register a new user

curl -X POST http://localhost:3000/api/local/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "jane@example.com",
    "password": "MySecurePass1",
    "first_name": "Jane",
    "last_name": "Doe"
  }'

Advanced: createUser must return the new user object

await fastify.register(xAuthLocal, {
  configs: [
    {
      name: "api",
      prefix: "/api",
      secret: process.env.JWT_SECRET,
      local: {
        enabled: true,
        userLookup: async (email) => db.users.findByEmail(email),
        // createUser receives { email, password (hashed), first_name, last_name }
        // and must return the persisted user object including id
        createUser: async (userData) => {
          const [user] = await db
            .insert(users)
            .values(userData)
            .returning();
          return user;
        },
      },
    },
  ],
});

See Also

AI Context

package: "@xenterprises/fastify-xauth-local"
route: POST {loginPath}/register
use-when: Built-in registration route — creates a new user account and returns a signed JWT
requires: local.enabled: true, local.createUser function
returns: { token: string }
Copyright © 2026