Documentation Index Fetch the complete documentation index at: https://mintlify.com/ihfaz297/MND/llms.txt
Use this file to discover all available pages before exploring further.
MND uses a passwordless magic link authentication system, providing a secure and user-friendly way to authenticate without requiring password management.
Overview
The authentication flow consists of two main steps:
Send magic link : User provides their email, system generates a temporary token
Verify token : User clicks the link, system validates the token and creates a session
Magic links expire after 15 minutes for security. Users must verify their email within this timeframe.
Authentication Flow
User requests magic link
The user submits their email address to receive a login link: curl -X POST \
-H "Content-Type: application/json" \
-d '{"email": "student@sust.edu"}' \
http://localhost:3000/api/auth/send-link
Response: {
"success" : true ,
"message" : "Magic link sent to your email" ,
"_dev" : {
"note" : "In production, this token would be sent via email only" ,
"token" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." ,
"verifyUrl" : "http://localhost:3000/api/auth/verify?token=eyJhbGciOiJI..."
}
}
The _dev field containing the token is only included in development mode for testing. In production, the token is sent exclusively via email.
System generates token
The backend creates a JWT token containing:
Email address
Token type (“magic_link”)
Expiration timestamp (15 minutes from creation)
The token is logged to the console and would be sent via email in production: 📧 Magic Link Generated
Email: student@sust.edu
Link: http://localhost:3000/api/auth/verify?token=...
Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Expires in: 15 minutes
User verifies the token
When the user clicks the magic link (or makes a verification request): curl "http://localhost:3000/api/auth/verify?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
Successful verification returns: {
"success" : true ,
"message" : "Login successful" ,
"authToken" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI3Y2QzOWE..." ,
"user" : {
"id" : "7cd39a42-9f8e-4c7d-a8f0-3e9b8c7d1234" ,
"email" : "student@sust.edu" ,
"createdAt" : "2026-03-05T08:00:00.000Z" ,
"lastLogin" : "2026-03-05T08:30:00.000Z"
}
}
Store the auth token
Save the authToken from the response for use in subsequent API requests: // Store in localStorage (web)
localStorage . setItem ( 'authToken' , response . authToken );
// Or secure storage (mobile)
await SecureStore . setItemAsync ( 'authToken' , response . authToken );
Making Authenticated Requests
Once authenticated, include the auth token in the Authorization header for protected endpoints:
curl -H "Authorization: Bearer YOUR_AUTH_TOKEN" \
http://localhost:3000/api/favorites
JavaScript Example
const authToken = localStorage . getItem ( 'authToken' );
const response = await fetch ( 'http://localhost:3000/api/favorites' , {
headers: {
'Authorization' : `Bearer ${ authToken } ` ,
'Content-Type' : 'application/json'
}
});
if ( response . status === 401 ) {
// Token expired or invalid - redirect to login
window . location . href = '/login' ;
}
Flutter/Dart Example
import 'package:http/http.dart' as http;
import 'package:flutter_secure_storage/flutter_secure_storage.dart' ;
final storage = FlutterSecureStorage ();
final authToken = await storage. read (key : 'authToken' );
final response = await http. get (
Uri . parse ( 'http://localhost:3000/api/favorites' ),
headers : {
'Authorization' : 'Bearer $ authToken ' ,
'Content-Type' : 'application/json' ,
},
);
if (response.statusCode == 401 ) {
// Token expired - redirect to login
Navigator . pushReplacementNamed (context, '/login' );
}
Protected Endpoints
The following endpoints require authentication:
Endpoint Method Description /api/favoritesGET List user’s saved favorites /api/favoritesPOST Create a new favorite /api/favorites/:idPUT Update a favorite /api/favorites/:idDELETE Delete a favorite /api/profileGET Get user profile
Getting User Profile
Retrieve the authenticated user’s profile information:
curl -H "Authorization: Bearer YOUR_AUTH_TOKEN" \
http://localhost:3000/api/profile
{
"user" : {
"id" : "7cd39a42-9f8e-4c7d-a8f0-3e9b8c7d1234" ,
"email" : "student@sust.edu" ,
"createdAt" : "2026-03-01T10:00:00.000Z" ,
"lastLogin" : "2026-03-05T08:30:00.000Z"
}
}
Logging Out
Invalidate the current auth token:
curl -X POST \
-H "Authorization: Bearer YOUR_AUTH_TOKEN" \
http://localhost:3000/api/auth/logout
Response:
{
"success" : true ,
"message" : "Logged out successfully"
}
After logging out, remove the token from local storage to prevent unauthorized access attempts.
// Clear token from storage
localStorage . removeItem ( 'authToken' );
// Redirect to login page
window . location . href = '/login' ;
Error Handling
When sending a magic link with an invalid email:
{
"error" : "Invalid email" ,
"message" : "Please provide a valid email address"
}
HTTP Status: 400 Bad Request
Missing Email
If the email field is not provided:
{
"error" : "Email is required" ,
"message" : "Please provide a valid email address"
}
HTTP Status: 400 Bad Request
Expired or Invalid Token
When verifying an expired or invalid magic link token:
{
"error" : "Verification failed" ,
"message" : "Invalid or expired token"
}
HTTP Status: 401 Unauthorized
Attempting to access a protected endpoint without an auth token:
{
"error" : "Unauthorized" ,
"message" : "Please provide a valid auth token"
}
HTTP Status: 401 Unauthorized
Invalid Auth Token
Using an expired or malformed auth token:
{
"error" : "Unauthorized" ,
"message" : "Invalid or expired token"
}
HTTP Status: 401 Unauthorized
Authentication Middleware
The backend provides two middleware functions for route protection:
requireAuth (Mandatory Authentication)
Use this middleware for endpoints that require authentication:
// src/api/authController.ts:200
router . get ( '/api/favorites' , requireAuth , getFavorites );
Rejects requests without valid auth tokens with a 401 response.
optionalAuth (Optional Authentication)
Use this for endpoints that work with or without authentication:
// src/api/authController.ts:182
router . get ( '/api/routes' , optionalAuth , planRoute );
If a valid token is provided, the user information is attached to the request. Otherwise, the request continues without user context.
Security Considerations
Web Applications:
Store tokens in localStorage or sessionStorage
Never store tokens in cookies without HttpOnly flag
Clear tokens on logout
Mobile Applications:
Use platform-specific secure storage (Keychain on iOS, Keystore on Android)
Flutter: Use flutter_secure_storage package
React Native: Use react-native-keychain or expo-secure-store
Tokens expire after 15 minutes
Each token can only be used once
Tokens are invalidated after verification
Use HTTPS in production to prevent token interception
Auth tokens remain valid until logout
Implement token refresh mechanism for long-running sessions
Monitor for 401 responses and redirect to login when detected
Store user ID alongside token for quick user identification
Email Integration (Production)
In production environments, integrate an email service to send magic links:
Using SendGrid
import sgMail from '@sendgrid/mail' ;
sgMail . setApiKey ( process . env . SENDGRID_API_KEY );
const msg = {
to: email ,
from: 'noreply@mnd.sust.edu' ,
subject: 'Your MND Login Link' ,
html: `
<h1>Login to MND</h1>
<p>Click the link below to log in to your account:</p>
<a href=" ${ magicLinkUrl } ">Log In</a>
<p>This link expires in 15 minutes.</p>
`
};
await sgMail . send ( msg );
Using Nodemailer
import nodemailer from 'nodemailer' ;
const transporter = nodemailer . createTransport ({
service: 'gmail' ,
auth: {
user: process . env . EMAIL_USER ,
pass: process . env . EMAIL_PASSWORD
}
});
await transporter . sendMail ({
from: 'noreply@mnd.sust.edu' ,
to: email ,
subject: 'Your MND Login Link' ,
html: `
<h1>Login to MND</h1>
<p>Click the link below to log in:</p>
<a href=" ${ magicLinkUrl } ">Log In</a>
<p>Expires in 15 minutes.</p>
`
});
Remove the _dev field from the response in production to avoid exposing tokens in API responses.
User Data Storage
User accounts are stored in users.json:
{
"users" : [
{
"id" : "7cd39a42-9f8e-4c7d-a8f0-3e9b8c7d1234" ,
"email" : "student@sust.edu" ,
"createdAt" : "2026-03-01T10:00:00.000Z" ,
"lastLogin" : "2026-03-05T08:30:00.000Z"
}
]
}
New users are automatically created on first login.
Implementation Reference
The authentication system is implemented in:
Core logic : src/core/auth.ts - Token generation, validation, user management
API endpoints : src/api/authController.ts - HTTP handlers and middleware
sendMagicLink() - Generate and send magic link (line 8)
verifyMagicLink() - Validate token and create session (line 65)
getProfile() - Retrieve user profile (line 113)
logout() - Invalidate auth token (line 157)
requireAuth() - Authentication middleware (line 200)
optionalAuth() - Optional authentication middleware (line 182)
Complete Authentication Example
Full React Implementation
import React , { useState , useEffect } from 'react' ;
function AuthExample () {
const [ email , setEmail ] = useState ( '' );
const [ user , setUser ] = useState ( null );
const [ token , setToken ] = useState ( localStorage . getItem ( 'authToken' ));
// Send magic link
async function sendMagicLink () {
const response = await fetch ( 'http://localhost:3000/api/auth/send-link' , {
method: 'POST' ,
headers: { 'Content-Type' : 'application/json' },
body: JSON . stringify ({ email })
});
const data = await response . json ();
if ( data . success ) {
alert ( 'Check your email for the login link!' );
// In dev mode, auto-verify for testing
if ( data . _dev ) {
await verifyToken ( data . _dev . token );
}
}
}
// Verify magic link token
async function verifyToken ( token ) {
const response = await fetch (
`http://localhost:3000/api/auth/verify?token= ${ token } `
);
const data = await response . json ();
if ( data . success ) {
localStorage . setItem ( 'authToken' , data . authToken );
setToken ( data . authToken );
setUser ( data . user );
}
}
// Fetch user profile
async function fetchProfile () {
const response = await fetch ( 'http://localhost:3000/api/profile' , {
headers: { 'Authorization' : `Bearer ${ token } ` }
});
if ( response . ok ) {
const data = await response . json ();
setUser ( data . user );
} else {
// Token invalid - clear and redirect to login
localStorage . removeItem ( 'authToken' );
setToken ( null );
}
}
// Logout
async function logout () {
await fetch ( 'http://localhost:3000/api/auth/logout' , {
method: 'POST' ,
headers: { 'Authorization' : `Bearer ${ token } ` }
});
localStorage . removeItem ( 'authToken' );
setToken ( null );
setUser ( null );
}
// Load user on mount if token exists
useEffect (() => {
if ( token ) {
fetchProfile ();
}
}, [ token ]);
// Render login form or user info
if ( ! user ) {
return (
< div >
< h1 > Login </ h1 >
< input
type = "email"
placeholder = "Email"
value = { email }
onChange = { ( e ) => setEmail ( e . target . value ) }
/>
< button onClick = { sendMagicLink } > Send Magic Link </ button >
</ div >
);
}
return (
< div >
< h1 > Welcome, { user . email } </ h1 >
< p > User ID: { user . id } </ p >
< p > Last login: {new Date ( user . lastLogin ). toLocaleString () } </ p >
< button onClick = { logout } > Logout </ button >
</ div >
);
}