Step 4: Handle the MFA response
⏱ 5 minProcess the MFA verification result and implement your security logic
MFA Response Structure
interface IdpAuthResponse {
success: boolean;
sid?: string; // Step-up Session ID (on success)
error?: string; // Error message (on failure)
timestamp: number; // Unix timestamp in milliseconds
action?: string; // Requested action type
}Basic Handling
const mfaResult = await transcodes.openAuthIdpModal({
resource: 'sensitive_action',
action: 'delete',
});
if (mfaResult.success && mfaResult.payload[0]?.success) {
const { sid, timestamp } = mfaResult.payload[0];
console.log(`Verified at ${new Date(timestamp)}`);
if (sid) console.log('Step-up Session ID:', sid);
// Proceed with protected action
await performSensitiveAction();
} else {
// User cancelled or verification failed
console.log('MFA verification not completed');
}MFA Verification Token
After successful MFA, you can get the access token to send to your server:
const mfaResult = await transcodes.openAuthIdpModal({
resource: 'admin_settings',
action: 'update',
});
if (mfaResult.success && mfaResult.payload[0]?.success) {
// Get the access token
const token = await transcodes.token.getAccessToken();
// Send to your server with the protected request
const response = await fetch('/api/admin/settings', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ setting: 'value' }),
});
}Server-Side Verification
On your server, verify the access token (which proves the user completed MFA). For full JWT verification setup, see Server-Side Integration:
// Node.js / Express
app.post('/api/admin/settings', async (req, res) => {
// Verify access token (user is logged in and completed MFA)
const accessToken = req.headers.authorization?.split(' ')[1];
const user = await verifyAccessToken(accessToken);
if (!user) {
return res.status(401).json({ error: 'Unauthorized' });
}
// Proceed with sensitive action
await updateSettings(req.body);
res.json({ success: true });
});MFA Session Caching
To avoid requiring MFA on every action, you can cache the MFA verification:
class MfaManager {
constructor() {
this.mfaVerifiedAt = null;
this.mfaValidDuration = 15 * 60 * 1000; // 15 minutes
}
async requireMfa() {
// Check if MFA was recently verified
if (this.isMfaValid()) {
return true;
}
// Prompt for MFA
const result = await transcodes.openAuthIdpModal({
resource: 'sensitive_action',
action: 'read',
});
if (result.success && result.payload[0]?.success) {
this.mfaVerifiedAt = Date.now();
return true;
}
return false;
}
isMfaValid() {
if (!this.mfaVerifiedAt) return false;
const elapsed = Date.now() - this.mfaVerifiedAt;
return elapsed < this.mfaValidDuration;
}
clearMfa() {
this.mfaVerifiedAt = null;
}
}
// Usage
const mfaManager = new MfaManager();
async function accessAdminPanel() {
if (await mfaManager.requireMfa()) {
// MFA valid - proceed
showAdminPanel();
}
}Best Practices
Security Recommendations:
- Always verify tokens server-side - Don’t trust client-side MFA alone
- Set reasonable MFA session duration - 15-30 minutes is typical
- Clear MFA on logout - Reset MFA cache when user logs out
- Log MFA events - Use
trackUserAction()for audit purposes
History Log
Record MFA and sensitive actions for audit logs using trackUserAction(). Events appear in the Audit Logs panel
// MFA verification success
if (mfaResult.success && mfaResult.payload[0]?.success) {
await transcodes.trackUserAction({
tag: 'admin:access',
severity: 'high',
status: true,
metadata: { action: 'read' },
});
}
// Sensitive action with webhook alert
await transcodes.trackUserAction(
{ tag: 'payment:transfer', severity: 'high', status: true, metadata: { amount: 1000 } },
{ webhookNotification: true }
);trackUserAction tag | Typical use (audit log) |
|---|---|
admin:access | Admin panel access |
user:delete | Account deletion |
document:delete | Document deletion |
payment:transfer | Financial transaction |
These tags are for trackUserAction() only. For openAuthIdpModal(), use resource + action (RBAC)—see Modal API.
See Audit API for full trackUserAction reference
Handle account without MFA
If the signed-in member has not set up MFA yet:
const mfaResult = await transcodes.openAuthIdpModal({
resource: 'sensitive_action',
action: 'delete',
forceStepUp: true,
});
if (!mfaResult.success || !mfaResult.payload[0]?.success) {
// Redirect to MFA setup in console panel
alert('Please set up MFA first');
await transcodes.openAuthConsoleModal(); // Opens console panel for MFA setup
}Congratulations!
🎉 You’ve successfully integrated Step-up MFA into your application!
Modal API for full openAuthIdpModal parameters