API Reference
Authentication API Reference
Complete reference for all authentication middleware, helpers, and utilities available in MoroJS. Built on Better Auth with native MoroJS integration.
Overview
Complete reference for all authentication middleware, helpers, and utilities available in MoroJS. Built on Better Auth with native MoroJS integration.
auth() Middleware
The main authentication middleware that integrates Better Auth with MoroJS. Handles OAuth flows, session management, and request enhancement.
1import { auth, providers } from '@morojs/moro';
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';
7
8// Basic authentication requirement
9app.get('/dashboard').use(requireAuth()).handler((req, res) => {
10 res.json({ user: req.auth.user });
11});
12
13// Role-based protection
14app.get('/admin').use(requireRole(['admin'])).handler((req, res) => {
15 res.json({ message: 'Admin panel' });
16});
17
18// Multiple roles allowed
19app.get('/moderator').use(requireRole(['admin', 'moderator'])).handler((req, res) => {
20 res.json({ message: 'Moderator panel' });
21});
22
23// Admin shorthand
24app.get('/admin/users').use(requireAdmin()).handler((req, res) => {
25 res.json({ users: getUserList() });
26});
27
28// Permission-based protection
29app.get('/api/users').use(requirePermission(['users:read'])).handler((req, res) => {
30 res.json({ users: getUsers() });
31});
32
33// Custom authorization logic
34app.get('/organization/:orgId').use(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})).handler((req, res) => {
43 res.json({ data: getOrganizationData(req.params.orgId) });
44});Authentication Utilities
Use authUtils for manual authentication checks and authResponses for standardized response patterns.
1import { authUtils, authResponses } from '@morojs/moro';
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 redirectNative Better Auth Adapter
Native Better Auth adapter with zero external dependencies. Direct integration with Better Auth core without Express compatibility layers.
1import { createAuthMiddleware } from '@morojs/moro';
2
3// Native Better Auth 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 Better Auth
24 request: (req) => ({
25 ...req,
26 headers: {
27 ...req.headers,
28 'x-forwarded-proto': 'https',
29 },
30 }),
31 // Transform Better Auth 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
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 Better Auth routes when the auth middleware is installed: