Node, React and MongoDB Headless CMS and Application Framework
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Complete user authentication and management system with login, password reset, email verification, and account locking capabilities. Payload provides built-in authentication for collections configured with auth enabled.
Authenticates a user with email and password credentials.
/**
* Authenticate a user with email and password
* @param options - Login options including collection, credentials, and configuration
* @returns Promise resolving to login result with user data and token
*/
function login<T>(options: LoginOptions): Promise<LoginResult & { user: T }>;
interface LoginOptions {
/** The auth-enabled collection slug (e.g., "users", "admins") */
collection: string;
/** Login credentials */
data: {
/** User's email address */
email: string;
/** User's password */
password: string;
};
/** Express request object (for cookie handling) */
req?: PayloadRequest;
/** Express response object (for cookie handling) */
res?: Response;
/** How many levels deep to populate user relationships */
depth?: number;
/** Locale for the operation */
locale?: string;
/** Fallback locale if content not found in specified locale */
fallbackLocale?: string;
/** Whether to override access control */
overrideAccess?: boolean;
/** Whether to include hidden fields */
showHiddenFields?: boolean;
}
interface LoginResult {
/** JWT token for authenticated requests (if not using cookies) */
token?: string;
/** The authenticated user document */
user: User;
/** Token expiration timestamp */
exp?: number;
}Usage Examples:
import payload from "payload";
// Basic login
const loginResult = await payload.login({
collection: "users",
data: {
email: "user@example.com",
password: "secure-password",
},
});
console.log("User:", loginResult.user);
console.log("Token:", loginResult.token);
// Login with populated relationships
const loginWithProfile = await payload.login({
collection: "users",
data: {
email: "user@example.com",
password: "secure-password",
},
depth: 1, // Populate user profile relationships
});
// Login in Express route (with cookies)
app.post("/api/login", async (req, res) => {
try {
const result = await payload.login({
collection: "users",
data: req.body,
req,
res,
});
res.json(result);
} catch (error) {
res.status(401).json({ error: error.message });
}
});Forgot password and reset password functionality for user account recovery.
/**
* Initiate password reset process by sending reset token to user's email
* @param options - Forgot password options
* @returns Promise resolving to forgot password result
*/
function forgotPassword(options: ForgotPasswordOptions): Promise<ForgotPasswordResult>;
/**
* Reset user password using a valid reset token
* @param options - Reset password options including token and new password
* @returns Promise resolving to reset password result
*/
function resetPassword(options: ResetPasswordOptions): Promise<ResetPasswordResult>;
interface ForgotPasswordOptions {
/** The auth-enabled collection slug */
collection: string;
/** User's email address */
data: {
email: string;
};
/** Express request object */
req?: PayloadRequest;
/** How many levels deep to populate user relationships */
depth?: number;
/** Locale for the operation */
locale?: string;
/** Fallback locale */
fallbackLocale?: string;
/** Whether to override access control */
overrideAccess?: boolean;
/** Whether to include hidden fields */
showHiddenFields?: boolean;
/** Token expiration time in seconds */
expiration?: number;
/** Disable sending the email */
disableEmail?: boolean;
}
interface ResetPasswordOptions {
/** The auth-enabled collection slug */
collection: string;
/** Reset data including token and new password */
data: {
/** Reset token from email */
token: string;
/** New password */
password: string;
};
/** Express request object */
req?: PayloadRequest;
/** How many levels deep to populate user relationships */
depth?: number;
/** Locale for the operation */
locale?: string;
/** Fallback locale */
fallbackLocale?: string;
/** Whether to override access control */
overrideAccess?: boolean;
/** Whether to include hidden fields */
showHiddenFields?: boolean;
}
interface ForgotPasswordResult {
/** Success message */
message: string;
}
interface ResetPasswordResult {
/** Success message */
message: string;
/** JWT token for immediate login */
token?: string;
/** The user document */
user?: User;
}Usage Examples:
// Initiate password reset
const forgotResult = await payload.forgotPassword({
collection: "users",
data: {
email: "user@example.com",
},
});
console.log(forgotResult.message); // "Check your email for a reset link"
// Reset password with token
const resetResult = await payload.resetPassword({
collection: "users",
data: {
token: "reset-token-from-email",
password: "new-secure-password",
},
});
console.log(resetResult.message); // "Password reset successfully"
console.log("Auto-login token:", resetResult.token);Email verification and account unlocking for enhanced security.
/**
* Verify user's email address using verification token
* @param options - Email verification options
* @returns Promise resolving to verification success status
*/
function verifyEmail(options: VerifyEmailOptions): Promise<boolean>;
/**
* Unlock a locked user account
* @param options - Account unlock options
* @returns Promise resolving to unlock success status
*/
function unlock(options: UnlockOptions): Promise<boolean>;
interface VerifyEmailOptions {
/** The auth-enabled collection slug */
collection: string;
/** Verification token from email */
token: string;
/** Express request object */
req?: PayloadRequest;
/** How many levels deep to populate user relationships */
depth?: number;
/** Locale for the operation */
locale?: string;
/** Fallback locale */
fallbackLocale?: string;
/** Whether to override access control */
overrideAccess?: boolean;
/** Whether to include hidden fields */
showHiddenFields?: boolean;
}
interface UnlockOptions {
/** The auth-enabled collection slug */
collection: string;
/** Unlock data including email */
data: {
/** User's email address */
email: string;
};
/** Express request object */
req?: PayloadRequest;
/** How many levels deep to populate user relationships */
depth?: number;
/** Locale for the operation */
locale?: string;
/** Fallback locale */
fallbackLocale?: string;
/** Whether to override access control */
overrideAccess?: boolean;
/** Whether to include hidden fields */
showHiddenFields?: boolean;
}Usage Examples:
// Verify email address
const isVerified = await payload.verifyEmail({
collection: "users",
token: "verification-token-from-email",
});
if (isVerified) {
console.log("Email verified successfully");
}
// Unlock account
const isUnlocked = await payload.unlock({
collection: "users",
data: {
email: "locked-user@example.com",
},
});
if (isUnlocked) {
console.log("Account unlocked successfully");
}Collections must be configured with authentication to use these operations.
interface CollectionConfig {
slug: string;
auth?: AuthConfig | boolean;
// ... other collection options
}
interface AuthConfig {
/** Token expires in (seconds) */
tokenExpiration?: number;
/** Maximum login attempts before locking */
maxLoginAttempts?: number;
/** Account lock duration (seconds) */
lockTime?: number;
/** Use email verification */
verify?: boolean | EmailVerificationConfig;
/** Forgot password configuration */
forgotPassword?: ForgotPasswordConfig;
/** Login rate limiting */
useAPIKey?: boolean;
/** Disable username (use email only) */
disableLocalStrategy?: boolean;
/** Custom login strategies */
strategies?: AuthStrategy[];
/** Cookie settings */
cookies?: CookieOptions;
}
interface EmailVerificationConfig {
/** Generate token function */
generateEmailHTML?: (args: {
token: string;
user: User;
}) => string;
/** Generate email subject */
generateEmailSubject?: (args: {
token: string;
user: User;
}) => string;
}
interface ForgotPasswordConfig {
/** Generate reset email HTML */
generateEmailHTML?: (args: {
token: string;
user: User;
}) => string;
/** Generate email subject */
generateEmailSubject?: (args: {
token: string;
user: User;
}) => string;
}interface User extends TypeWithID {
/** User's email address */
email?: string;
/** Password reset token */
resetPasswordToken?: string;
/** Reset token expiration */
resetPasswordExpiration?: string;
/** Password salt */
salt?: string;
/** Password hash */
hash?: string;
/** Failed login attempts count */
loginAttempts?: number;
/** Account lock expiration timestamp */
lockUntil?: number;
/** Email verification status */
_verified?: boolean;
/** Email verification token */
_verificationToken?: string;
/** API key for API authentication */
apiKey?: string;
/** Whether account is enabled */
enableAPIKey?: boolean;
}
interface PayloadRequest extends Request {
/** Authenticated user */
user?: User;
/** Request locale */
locale?: string;
/** Fallback locale */
fallbackLocale?: string;
/** Request payload */
payload: Payload;
}Complete authentication configuration for collections with auth enabled.
/**
* Authentication configuration for collections
*/
interface AuthConfig {
/** JWT token expiration time in seconds (default: 7200) */
tokenExpiration?: number;
/** Email verification configuration */
verify?: boolean | VerifyConfig;
/** Maximum login attempts before account lock */
maxLoginAttempts?: number;
/** Account lock duration in milliseconds */
lockTime?: number;
/** Enable API key authentication */
useAPIKey?: boolean;
/** Population depth for user documents */
depth?: number;
/** Cookie configuration */
cookies?: CookieConfig;
/** Forgot password email configuration */
forgotPassword?: ForgotPasswordConfig;
/** Disable local username/password strategy */
disableLocalStrategy?: boolean;
/** Custom authentication strategies */
strategies?: AuthStrategy[];
}
/**
* Email verification configuration
*/
interface VerifyConfig {
/** Function to generate verification email HTML */
generateEmailHTML?: (args: {
req: PayloadRequest;
token: string;
user: any;
}) => Promise<string> | string;
/** Function to generate verification email subject */
generateEmailSubject?: (args: {
req: PayloadRequest;
token: string;
user: any;
}) => Promise<string> | string;
}
/**
* Cookie configuration for auth
*/
interface CookieConfig {
/** Use secure cookies (HTTPS only) */
secure?: boolean;
/** SameSite cookie attribute */
sameSite?: boolean | 'none' | 'strict' | 'lax';
/** Cookie domain */
domain?: string;
}
/**
* Forgot password email configuration
*/
interface ForgotPasswordConfig {
/** Function to generate password reset email HTML */
generateEmailHTML?: (args: {
req?: PayloadRequest;
token?: string;
user?: unknown;
}) => Promise<string> | string;
/** Function to generate password reset email subject */
generateEmailSubject?: (args: {
req?: PayloadRequest;
token?: string;
user?: any;
}) => Promise<string> | string;
}
/**
* Custom authentication strategy
*/
interface AuthStrategy {
/** Strategy name */
name?: string;
/** Passport strategy instance or factory */
strategy: Strategy | ((payload: Payload) => Strategy);
}Authentication Configuration Examples:
// Basic auth configuration
const UsersCollection: CollectionConfig = {
slug: "users",
auth: {
tokenExpiration: 7200, // 2 hours
verify: true, // Enable email verification
maxLoginAttempts: 5,
lockTime: 600000, // 10 minutes
useAPIKey: true,
},
fields: [
{
name: "firstName",
type: "text",
required: true,
},
{
name: "lastName",
type: "text",
required: true,
},
],
};
// Advanced auth with custom emails
const AdvancedUsersCollection: CollectionConfig = {
slug: "users",
auth: {
tokenExpiration: 86400, // 24 hours
verify: {
generateEmailHTML: ({ user, token, req }) => {
return `
<h1>Welcome ${user.firstName}!</h1>
<p>Please verify your email by clicking the link below:</p>
<a href="${req.payload.getAdminURL()}/verify/${token}">
Verify Email
</a>
`;
},
generateEmailSubject: ({ user }) => {
return `Welcome ${user.firstName} - Please verify your email`;
},
},
forgotPassword: {
generateEmailHTML: ({ user, token, req }) => {
return `
<h1>Password Reset</h1>
<p>Click the link below to reset your password:</p>
<a href="${req.payload.getAdminURL()}/reset-password/${token}">
Reset Password
</a>
`;
},
generateEmailSubject: () => {
return "Reset your password";
},
},
cookies: {
secure: process.env.NODE_ENV === "production",
sameSite: "lax",
domain: process.env.COOKIE_DOMAIN,
},
},
fields: [
{
name: "role",
type: "select",
options: ["admin", "editor", "user"],
defaultValue: "user",
},
],
};
// Custom OAuth strategies
const OAuthUsersCollection: CollectionConfig = {
slug: "users",
auth: {
disableLocalStrategy: true, // Only use OAuth
strategies: [
{
name: "google",
strategy: new GoogleStrategy(
{
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: "/auth/google/callback",
},
async (accessToken, refreshToken, profile, done) => {
// Find or create user logic
const user = await payload.find({
collection: "users",
where: {
googleId: {
equals: profile.id,
},
},
});
return done(null, user.docs[0] || null);
}
),
},
],
},
fields: [
{
name: "googleId",
type: "text",
hidden: true,
},
],
};Comprehensive permission system for controlling access to collections, globals, and fields.
/**
* Base permission result
*/
interface Permission {
/** Whether access is allowed */
permission: boolean;
/** Optional query constraint */
where?: Record<string, unknown>;
}
/**
* Field-level permissions
*/
interface FieldPermissions {
/** Create permission */
create: {
permission: boolean;
};
/** Read permission */
read: {
permission: boolean;
};
/** Update permission */
update: {
permission: boolean;
};
/** Nested field permissions */
fields?: {
[fieldName: string]: FieldPermissions;
};
}
/**
* Collection-level permissions
*/
interface CollectionPermission {
/** Create document permission */
create: Permission;
/** Read document permission */
read: Permission;
/** Update document permission */
update: Permission;
/** Delete document permission */
delete: Permission;
/** Field-level permissions */
fields: {
[fieldName: string]: FieldPermissions;
};
}
/**
* Global-level permissions
*/
interface GlobalPermission {
/** Read global permission */
read: Permission;
/** Update global permission */
update: Permission;
/** Field-level permissions */
fields: {
[fieldName: string]: FieldPermissions;
};
}
/**
* Complete user permissions
*/
interface Permissions {
/** Whether user can access admin panel */
canAccessAdmin: boolean;
/** Collection permissions */
collections: CollectionPermission[];
/** Global permissions */
globals?: GlobalPermission[];
}
/**
* User document with authentication methods
*/
interface UserDocument extends PayloadMongooseDocument {
/** Set user password */
setPassword: (password: string) => Promise<void>;
/** Authenticate user with password */
authenticate: (password: string) => Promise<void>;
/** Password reset expiration timestamp */
resetPasswordExpiration: number;
/** User email */
email: string;
}Permission Configuration Examples:
// Role-based permissions
const PostsCollection: CollectionConfig = {
slug: "posts",
access: {
read: ({ req: { user } }) => {
// Anyone can read published posts
if (!user) {
return {
status: {
equals: "published",
},
};
}
// Authors can read their own posts
if (user.role === "author") {
return {
or: [
{
status: {
equals: "published",
},
},
{
author: {
equals: user.id,
},
},
],
};
}
// Admins can read all posts
return user.role === "admin";
},
create: ({ req: { user } }) => {
return user && ["admin", "author"].includes(user.role);
},
update: ({ req: { user } }) => {
if (!user) return false;
if (user.role === "admin") return true;
// Authors can only update their own posts
if (user.role === "author") {
return {
author: {
equals: user.id,
},
};
}
return false;
},
delete: ({ req: { user } }) => {
return user && user.role === "admin";
},
},
fields: [
{
name: "title",
type: "text",
access: {
read: () => true, // Anyone can read title
update: ({ req: { user } }) => {
return user && ["admin", "author"].includes(user.role);
},
},
},
{
name: "status",
type: "select",
options: ["draft", "published"],
access: {
read: () => true,
update: ({ req: { user } }) => {
// Only admins can change status
return user && user.role === "admin";
},
},
},
],
};Install with Tessl CLI
npx tessl i tessl/npm-payload