Fix jwt-token

This commit is contained in:
2025-09-13 14:23:01 +02:00
parent 02b1b6f62f
commit 181bd9cfa4
4 changed files with 798 additions and 8 deletions

View File

@@ -450,4 +450,266 @@ router.put('/users/:userId/status', authenticateToken, requirePermissions(['user
}
});
/**
* GET /tenant/auth
* Get authentication configuration (auth admins or higher)
*/
router.get('/auth', authenticateToken, requirePermissions(['auth.view']), async (req, res) => {
try {
// Determine tenant from request
const tenantId = await multiAuth.determineTenant(req);
if (!tenantId) {
return res.status(400).json({
success: false,
message: 'Unable to determine tenant'
});
}
const tenant = await Tenant.findOne({ where: { slug: tenantId } });
if (!tenant) {
return res.status(404).json({
success: false,
message: 'Tenant not found'
});
}
// Return auth configuration (excluding sensitive credentials)
const authConfig = {
auth_provider: tenant.auth_provider,
auth_config: tenant.auth_config ? {
...tenant.auth_config,
// Hide sensitive fields
client_secret: tenant.auth_config.client_secret ? '***HIDDEN***' : undefined,
bind_password: tenant.auth_config.bind_password ? '***HIDDEN***' : undefined,
service_password: tenant.auth_config.service_password ? '***HIDDEN***' : undefined,
certificate: tenant.auth_config.certificate ? '***HIDDEN***' : undefined
} : {},
session_timeout: tenant.session_timeout || 480,
require_mfa: tenant.require_mfa || false,
allow_concurrent_sessions: tenant.allow_concurrent_sessions !== false
};
console.log(`✅ Auth config retrieved for tenant "${tenantId}" by "${req.user.username}"`);
res.json({
success: true,
data: authConfig
});
} catch (error) {
console.error('Error retrieving auth config:', error);
res.status(500).json({
success: false,
message: 'Failed to retrieve authentication configuration'
});
}
});
/**
* PUT /tenant/auth
* Update authentication configuration (auth admins or higher)
*/
router.put('/auth', authenticateToken, requirePermissions(['auth.edit']), async (req, res) => {
try {
// Determine tenant from request
const tenantId = await multiAuth.determineTenant(req);
if (!tenantId) {
return res.status(400).json({
success: false,
message: 'Unable to determine tenant'
});
}
const tenant = await Tenant.findOne({ where: { slug: tenantId } });
if (!tenant) {
return res.status(404).json({
success: false,
message: 'Tenant not found'
});
}
const {
auth_provider,
auth_config,
session_timeout,
require_mfa,
allow_concurrent_sessions,
role_mappings
} = req.body;
// Validate auth provider
const validProviders = ['local', 'saml', 'oauth', 'ldap', 'ad'];
if (auth_provider && !validProviders.includes(auth_provider)) {
return res.status(400).json({
success: false,
message: 'Invalid authentication provider'
});
}
// Validate session timeout
if (session_timeout && (session_timeout < 15 || session_timeout > 1440)) {
return res.status(400).json({
success: false,
message: 'Session timeout must be between 15 and 1440 minutes'
});
}
// Prepare update data
const updateData = {};
if (auth_provider) updateData.auth_provider = auth_provider;
if (auth_config) {
// Merge with existing config, preserving hidden sensitive fields
const existingConfig = tenant.auth_config || {};
updateData.auth_config = {
...existingConfig,
...auth_config,
// Restore hidden fields if they weren't changed
client_secret: auth_config.client_secret === '***HIDDEN***' ? existingConfig.client_secret : auth_config.client_secret,
bind_password: auth_config.bind_password === '***HIDDEN***' ? existingConfig.bind_password : auth_config.bind_password,
service_password: auth_config.service_password === '***HIDDEN***' ? existingConfig.service_password : auth_config.service_password,
certificate: auth_config.certificate === '***HIDDEN***' ? existingConfig.certificate : auth_config.certificate
};
}
if (session_timeout !== undefined) updateData.session_timeout = session_timeout;
if (require_mfa !== undefined) updateData.require_mfa = require_mfa;
if (allow_concurrent_sessions !== undefined) updateData.allow_concurrent_sessions = allow_concurrent_sessions;
if (role_mappings) updateData.role_mappings = role_mappings;
// Update tenant
await tenant.update(updateData);
console.log(`✅ Auth config updated for tenant "${tenantId}" by admin "${req.user.username}"`);
// Return updated config (with hidden sensitive fields)
const updatedConfig = {
auth_provider: tenant.auth_provider,
auth_config: tenant.auth_config ? {
...tenant.auth_config,
client_secret: tenant.auth_config.client_secret ? '***HIDDEN***' : undefined,
bind_password: tenant.auth_config.bind_password ? '***HIDDEN***' : undefined,
service_password: tenant.auth_config.service_password ? '***HIDDEN***' : undefined,
certificate: tenant.auth_config.certificate ? '***HIDDEN***' : undefined
} : {},
session_timeout: tenant.session_timeout,
require_mfa: tenant.require_mfa,
allow_concurrent_sessions: tenant.allow_concurrent_sessions,
role_mappings: tenant.role_mappings
};
res.json({
success: true,
message: 'Authentication configuration updated successfully',
data: updatedConfig
});
} catch (error) {
console.error('Error updating auth config:', error);
res.status(500).json({
success: false,
message: 'Failed to update authentication configuration'
});
}
});
/**
* POST /tenant/auth/test
* Test authentication configuration (auth admins or higher)
*/
router.post('/auth/test', authenticateToken, requirePermissions(['auth.edit']), async (req, res) => {
try {
// Determine tenant from request
const tenantId = await multiAuth.determineTenant(req);
if (!tenantId) {
return res.status(400).json({
success: false,
message: 'Unable to determine tenant'
});
}
const tenant = await Tenant.findOne({ where: { slug: tenantId } });
if (!tenant) {
return res.status(404).json({
success: false,
message: 'Tenant not found'
});
}
const { test_username, test_password } = req.body;
// Simulate authentication test based on provider
const authProvider = tenant.auth_provider;
let testResult = {
success: false,
message: 'Authentication test not implemented for this provider',
details: {}
};
switch (authProvider) {
case 'local':
testResult = {
success: true,
message: 'Local authentication is always available',
details: { provider: 'local' }
};
break;
case 'saml':
// In real implementation, this would test SAML SSO endpoint
testResult = {
success: true,
message: 'SAML configuration appears valid (test connection would be performed in production)',
details: {
provider: 'saml',
sso_url: tenant.auth_config?.sso_url,
entity_id: tenant.auth_config?.entity_id
}
};
break;
case 'oauth':
// In real implementation, this would test OAuth endpoint
testResult = {
success: true,
message: 'OAuth configuration appears valid (test connection would be performed in production)',
details: {
provider: 'oauth',
oauth_provider: tenant.auth_config?.oauth_provider,
client_id: tenant.auth_config?.client_id
}
};
break;
case 'ldap':
case 'ad':
// In real implementation, this would test LDAP/AD connection
testResult = {
success: true,
message: `${authProvider.toUpperCase()} configuration appears valid (test connection would be performed in production)`,
details: {
provider: authProvider,
server: tenant.auth_config?.ldap_server || tenant.auth_config?.domain_controller
}
};
break;
}
console.log(`✅ Auth test performed for tenant "${tenantId}" by admin "${req.user.username}"`);
res.json({
success: true,
message: 'Authentication test completed',
data: testResult
});
} catch (error) {
console.error('Error testing auth config:', error);
res.status(500).json({
success: false,
message: 'Failed to test authentication configuration'
});
}
});
module.exports = router;