Authentication API

Complete API reference for MoroJS authentication middleware, helpers, and utilities.

Authentication API Reference

Complete reference for all authentication middleware, helpers, and utilities available in MoroJS. Built on Auth.js with native MoroJS integration.

auth() Middleware

The main authentication middleware that integrates Auth.js with MoroJS. Handles OAuth flows, session management, and request enhancement.

1import { auth, providers } from '@morojs/moro/auth';
2
3// Basic auth middleware
4app.use(auth({
5  providers: [
6    providers.github({
7      clientId: process.env.GITHUB_CLIENT_ID!,
8      clientSecret: process.env.GITHUB_CLIENT_SECRET!,
9    }),
10  ],
11  secret: process.env.AUTH_SECRET,
12  
13  // Optional configuration
14  session: {
15    strategy: 'jwt', // or 'database'
16    maxAge: 8 * 60 * 60, // 8 hours
17    updateAge: 2 * 60 * 60, // Update every 2 hours
18  },
19  
20  // Security settings
21  useSecureCookies: process.env.NODE_ENV === 'production',
22  trustHost: true,
23  debug: process.env.NODE_ENV === 'development',
24  
25  // Custom callbacks
26  callbacks: {
27    async signIn({ user, account, profile }) {
28      // Custom sign-in logic
29      return true;
30    },
31    async session({ session, token }) {
32      // Add custom fields to session
33      session.user.roles = token.roles;
34      return session;
35    },
36    async jwt({ token, user, account }) {
37      // Add custom claims to JWT
38      if (user) {
39        token.roles = await getUserRoles(user.id);
40      }
41      return token;
42    },
43  },
44  
45  // Security events
46  events: {
47    async signIn({ user, account, isNewUser }) {
48      await logSecurityEvent('signin_success', {
49        userId: user.id,
50        provider: account?.provider,
51        isNewUser,
52      });
53    },
54  },
55}));

Route Protection Middleware

requireAuth()

Basic authentication requirement with optional custom authorization

requireRole()

Role-based access control with support for multiple roles

requireAdmin()

Shorthand for admin role requirement

requirePermission()

Fine-grained permission-based access control

1import { 
2  requireAuth, 
3  requireRole, 
4  requireAdmin, 
5  requirePermission 
6} from '@morojs/moro/auth';
7
8// Basic authentication requirement
9app.get('/dashboard', requireAuth(), (req, res) => {
10  res.json({ user: req.auth.user });
11});
12
13// Role-based protection
14app.get('/admin', requireRole(['admin']), (req, res) => {
15  res.json({ message: 'Admin panel' });
16});
17
18// Multiple roles allowed
19app.get('/moderator', requireRole(['admin', 'moderator']), (req, res) => {
20  res.json({ message: 'Moderator panel' });
21});
22
23// Admin shorthand
24app.get('/admin/users', requireAdmin(), (req, res) => {
25  res.json({ users: getUserList() });
26});
27
28// Permission-based protection
29app.get('/api/users', requirePermission(['users:read']), (req, res) => {
30  res.json({ users: getUsers() });
31});
32
33// Custom authorization logic
34app.get('/organization/:orgId', requireAuth({
35  authorize: async (user, req) => {
36    // Custom logic - user can only access their organization's data
37    return user.organizationId === req.params.orgId;
38  },
39  onForbidden: (req, res) => {
40    res.status(403).json({ error: 'Access denied to this organization' });
41  },
42}), (req, res) => {
43  res.json({ data: getOrganizationData(req.params.orgId) });
44});

Authentication Utilities

Manual Authentication Checks

Use authUtils for manual authentication checks and authResponses for standardized response patterns.

1import { authUtils, authResponses } from '@morojs/moro/auth';
2
3app.get('/profile/settings', (req, res) => {
4  // Manual authentication check
5  if (!authUtils.isAuthenticated(req)) {
6    return authResponses.unauthorized(res, 'Please sign in');
7  }
8
9  // Manual role check
10  if (!authUtils.hasRole(req, ['user', 'premium'])) {
11    return authResponses.forbidden(res, 'Premium access required');
12  }
13
14  // Manual permission check
15  if (!authUtils.hasPermission(req, 'settings:write')) {
16    return authResponses.forbidden(res, 'Write permission required');
17  }
18
19  const userId = authUtils.getUserId(req);
20  
21  res.json({
22    userId,
23    settings: getUserSettings(userId),
24  });
25});
26
27// Available utility functions:
28authUtils.isAuthenticated(req)           // Check if user is authenticated
29authUtils.getUser(req)                   // Get current user object
30authUtils.getUserId(req)                 // Get current user ID
31authUtils.hasRole(req, 'admin')          // Check if user has specific role
32authUtils.hasRole(req, ['admin', 'mod']) // Check if user has any of the roles
33authUtils.hasPermission(req, 'users:read') // Check specific permission
34authUtils.isAdmin(req)                   // Check if user is admin
35authUtils.createAuthResponse(req)        // Create standardized auth response
36authUtils.ensureAuth(req, res)           // Force auth check with redirect

Native Auth.js Adapter

createAuthMiddleware()

Native Auth.js adapter with zero external dependencies. Direct integration with Auth.js core without Express compatibility layers.

1import { createAuthMiddleware } from '@morojs/moro/native-auth';
2
3// Native Auth.js adapter (zero Express dependencies)
4app.use(createAuthMiddleware({
5  providers: [
6    {
7      id: 'github',
8      name: 'GitHub',
9      type: 'oauth',
10      authorization: 'https://github.com/login/oauth/authorize',
11      token: 'https://github.com/login/oauth/access_token',
12      userinfo: 'https://api.github.com/user',
13      clientId: process.env.GITHUB_CLIENT_ID!,
14      clientSecret: process.env.GITHUB_CLIENT_SECRET!,
15    },
16  ],
17  secret: process.env.AUTH_SECRET!,
18  
19  // MoroJS-specific options
20  morojs: {
21    debug: true,
22    transformers: {
23      // Transform MoroJS request for Auth.js
24      request: (req) => ({
25        ...req,
26        headers: {
27          ...req.headers,
28          'x-forwarded-proto': 'https',
29        },
30      }),
31      // Transform Auth.js response for MoroJS
32      response: (res) => res,
33    },
34  },
35  
36  callbacks: {
37    async signIn({ user, account }) {
38      console.log(`🔐 User ${user.email} signing in via ${account?.provider}`);
39      return true;
40    },
41  },
42}));

Authentication Request Object

req.auth Object

The authentication middleware automatically adds an auth object to all requests with user information and helper methods.

1// The req.auth object is automatically added to all requests
2interface AuthRequest {
3  user?: AuthUser;
4  session?: AuthSession;
5  token?: string;
6  isAuthenticated: boolean;
7
8  // Helper methods
9  signIn(provider?: string, options?: SignInOptions): Promise<any>;
10  signOut(options?: SignOutOptions): Promise<any>;
11  getSession(): Promise<AuthSession | null>;
12  getToken(): Promise<AuthJWT | null>;
13  getCsrfToken(): Promise<string>;
14  getProviders(): Promise<Record<string, AuthProvider>>;
15}
16
17// Usage in route handlers
18app.get('/protected', (req, res) => {
19  const { user, session, isAuthenticated } = req.auth;
20  
21  if (!isAuthenticated) {
22    return res.status(401).json({ error: 'Unauthorized' });
23  }
24  
25  res.json({
26    message: 'Protected resource',
27    user: user,
28    sessionData: session?.customData,
29  });
30});

Authentication Routes

MoroJS automatically handles these Auth.js routes when the auth middleware is installed:

GET/api/auth/signin
POST/api/auth/signin/:provider
GET/api/auth/signout
POST/api/auth/signout
GET/api/auth/session
GET/api/auth/csrf
GET/api/auth/providers
GET/api/auth/callback/:provider

Next Steps