Fix jwt-token

This commit is contained in:
2025-09-13 21:09:59 +02:00
parent 4e234c0bfc
commit a6c3b6aaf1
3 changed files with 149 additions and 46 deletions

View File

@@ -279,6 +279,33 @@ class MultiTenantAuth {
{ expiresIn: '24h' }
);
}
/**
* Determine tenant from request (slug or subdomain)
*/
async determineTenant(req) {
try {
// Try to get tenant from subdomain first
const host = req.get('host') || '';
const subdomain = host.split('.')[0];
// If subdomain is not localhost/IP, use it as tenant slug
if (subdomain && !subdomain.match(/^(localhost|127\.0\.0\.1|\d+\.\d+\.\d+\.\d+)$/)) {
return subdomain;
}
// Fallback: get from user's tenant if authenticated
if (req.user && req.user.tenant_id) {
const tenant = await Tenant.findByPk(req.user.tenant_id);
return tenant ? tenant.slug : null;
}
return null;
} catch (error) {
console.error('Error determining tenant:', error);
return null;
}
}
}
module.exports = MultiTenantAuth;

View File

@@ -35,12 +35,20 @@ router.get('/rules', authenticateToken, async (req, res) => {
// Initialize multi-tenant auth to determine tenant
const multiTenantAuth = new MultiTenantAuth();
const tenantId = await multiTenantAuth.determineTenant(req);
const tenantSlug = await multiTenantAuth.determineTenant(req);
if (!tenantId) {
return res.status(403).json({
if (!tenantSlug) {
return res.status(400).json({
success: false,
message: 'Access denied: No tenant context'
message: 'Unable to determine tenant'
});
}
const tenant = await Tenant.findOne({ where: { slug: tenantSlug } });
if (!tenant) {
return res.status(404).json({
success: false,
message: 'Tenant not found'
});
}
@@ -53,7 +61,7 @@ router.get('/rules', authenticateToken, async (req, res) => {
include: [{
model: User,
as: 'user',
where: { tenant_id: tenantId },
where: { tenant_id: tenant.id },
attributes: ['id', 'username', 'email']
}],
limit: Math.min(parseInt(limit), 100),
@@ -126,12 +134,20 @@ router.put('/rules/:id', authenticateToken, validateRequest(alertRuleSchema), as
try {
// Initialize multi-tenant auth to determine tenant
const multiTenantAuth = new MultiTenantAuth();
const tenantId = await multiTenantAuth.determineTenant(req);
const tenantSlug = await multiTenantAuth.determineTenant(req);
if (!tenantId) {
return res.status(403).json({
if (!tenantSlug) {
return res.status(400).json({
success: false,
message: 'Access denied: No tenant context'
message: 'Unable to determine tenant'
});
}
const tenant = await Tenant.findOne({ where: { slug: tenantSlug } });
if (!tenant) {
return res.status(404).json({
success: false,
message: 'Tenant not found'
});
}
@@ -142,7 +158,7 @@ router.put('/rules/:id', authenticateToken, validateRequest(alertRuleSchema), as
include: [{
model: User,
as: 'user',
where: { tenant_id: tenantId },
where: { tenant_id: tenant.id },
attributes: ['id']
}]
});
@@ -177,12 +193,20 @@ router.delete('/rules/:id', authenticateToken, async (req, res) => {
try {
// Initialize multi-tenant auth to determine tenant
const multiTenantAuth = new MultiTenantAuth();
const tenantId = await multiTenantAuth.determineTenant(req);
const tenantSlug = await multiTenantAuth.determineTenant(req);
if (!tenantId) {
return res.status(403).json({
if (!tenantSlug) {
return res.status(400).json({
success: false,
message: 'Access denied: No tenant context'
message: 'Unable to determine tenant'
});
}
const tenant = await Tenant.findOne({ where: { slug: tenantSlug } });
if (!tenant) {
return res.status(404).json({
success: false,
message: 'Tenant not found'
});
}
@@ -193,7 +217,7 @@ router.delete('/rules/:id', authenticateToken, async (req, res) => {
include: [{
model: User,
as: 'user',
where: { tenant_id: tenantId },
where: { tenant_id: tenant.id },
attributes: ['id']
}]
});
@@ -236,12 +260,20 @@ router.get('/logs', authenticateToken, async (req, res) => {
// Initialize multi-tenant auth to determine tenant
const multiTenantAuth = new MultiTenantAuth();
const tenantId = await multiTenantAuth.determineTenant(req);
const tenantSlug = await multiTenantAuth.determineTenant(req);
if (!tenantId) {
return res.status(403).json({
if (!tenantSlug) {
return res.status(400).json({
success: false,
message: 'Access denied: No tenant context'
message: 'Unable to determine tenant'
});
}
const tenant = await Tenant.findOne({ where: { slug: tenantSlug } });
if (!tenant) {
return res.status(404).json({
success: false,
message: 'Tenant not found'
});
}
@@ -263,7 +295,7 @@ router.get('/logs', authenticateToken, async (req, res) => {
include: [{
model: User,
as: 'user',
where: { tenant_id: tenantId },
where: { tenant_id: tenant.id },
attributes: ['id', 'username']
}],
attributes: ['id', 'name', 'priority']
@@ -302,12 +334,20 @@ router.get('/stats', authenticateToken, async (req, res) => {
// Initialize multi-tenant auth to determine tenant
const multiTenantAuth = new MultiTenantAuth();
const tenantId = await multiTenantAuth.determineTenant(req);
const tenantSlug = await multiTenantAuth.determineTenant(req);
if (!tenantId) {
return res.status(403).json({
if (!tenantSlug) {
return res.status(400).json({
success: false,
message: 'Access denied: No tenant context'
message: 'Unable to determine tenant'
});
}
const tenant = await Tenant.findOne({ where: { slug: tenantSlug } });
if (!tenant) {
return res.status(404).json({
success: false,
message: 'Tenant not found'
});
}
@@ -316,7 +356,7 @@ router.get('/stats', authenticateToken, async (req, res) => {
include: [{
model: User,
as: 'user',
where: { tenant_id: tenantId },
where: { tenant_id: tenant.id },
attributes: []
}],
attributes: ['id']

View File

@@ -14,17 +14,25 @@ router.get('/overview', authenticateToken, async (req, res) => {
// Initialize multi-tenant auth to determine tenant
const multiTenantAuth = new MultiTenantAuth();
const tenantId = await multiTenantAuth.determineTenant(req);
const tenantSlug = await multiTenantAuth.determineTenant(req);
if (!tenantId) {
return res.status(403).json({
if (!tenantSlug) {
return res.status(400).json({
success: false,
message: 'Access denied: No tenant context'
message: 'Unable to determine tenant'
});
}
const tenant = await Tenant.findOne({ where: { slug: tenantSlug } });
if (!tenant) {
return res.status(404).json({
success: false,
message: 'Tenant not found'
});
}
// Create base filter for tenant devices
const tenantDeviceFilter = { tenant_id: tenantId };
const tenantDeviceFilter = { tenant_id: tenant.id };
// Get basic statistics - filtered by tenant
const [
@@ -39,6 +47,7 @@ router.get('/overview', authenticateToken, async (req, res) => {
DroneDetection.count({
include: [{
model: Device,
as: 'device',
where: tenantDeviceFilter,
attributes: []
}],
@@ -47,6 +56,7 @@ router.get('/overview', authenticateToken, async (req, res) => {
DroneDetection.count({
include: [{
model: Device,
as: 'device',
where: tenantDeviceFilter,
attributes: []
}],
@@ -58,6 +68,7 @@ router.get('/overview', authenticateToken, async (req, res) => {
DroneDetection.count({
include: [{
model: Device,
as: 'device',
where: tenantDeviceFilter,
attributes: []
}],
@@ -145,12 +156,20 @@ router.get('/activity', authenticateToken, async (req, res) => {
// Initialize multi-tenant auth to determine tenant
const multiTenantAuth = new MultiTenantAuth();
const tenantId = await multiTenantAuth.determineTenant(req);
const tenantSlug = await multiTenantAuth.determineTenant(req);
if (!tenantId) {
return res.status(403).json({
if (!tenantSlug) {
return res.status(400).json({
success: false,
message: 'Access denied: No tenant context'
message: 'Unable to determine tenant'
});
}
const tenant = await Tenant.findOne({ where: { slug: tenantSlug } });
if (!tenant) {
return res.status(404).json({
success: false,
message: 'Tenant not found'
});
}
@@ -163,7 +182,7 @@ router.get('/activity', authenticateToken, async (req, res) => {
include: [{
model: Device,
as: 'device',
where: { tenant_id: tenantId },
where: { tenant_id: tenant.id },
attributes: ['id', 'name', 'geo_lat', 'geo_lon', 'location_description']
}],
limit: Math.min(parseInt(limit), 200),
@@ -176,7 +195,7 @@ router.get('/activity', authenticateToken, async (req, res) => {
include: [{
model: Device,
as: 'device',
where: { tenant_id: tenantId },
where: { tenant_id: tenant.id },
attributes: ['id', 'name', 'geo_lat', 'geo_lon']
}],
limit: Math.min(parseInt(limit), 50),
@@ -239,12 +258,20 @@ router.get('/charts/detections', authenticateToken, async (req, res) => {
// Initialize multi-tenant auth to determine tenant
const multiTenantAuth = new MultiTenantAuth();
const tenantId = await multiTenantAuth.determineTenant(req);
const tenantSlug = await multiTenantAuth.determineTenant(req);
if (!tenantId) {
return res.status(403).json({
if (!tenantSlug) {
return res.status(400).json({
success: false,
message: 'Access denied: No tenant context'
message: 'Unable to determine tenant'
});
}
const tenant = await Tenant.findOne({ where: { slug: tenantSlug } });
if (!tenant) {
return res.status(404).json({
success: false,
message: 'Tenant not found'
});
}
@@ -266,7 +293,8 @@ router.get('/charts/detections', authenticateToken, async (req, res) => {
const detectionCounts = await DroneDetection.findAll({
include: [{
model: Device,
where: { tenant_id: tenantId },
as: 'device',
where: { tenant_id: tenant.id },
attributes: []
}],
where: {
@@ -308,12 +336,20 @@ router.get('/charts/devices', authenticateToken, async (req, res) => {
// Initialize multi-tenant auth to determine tenant
const multiTenantAuth = new MultiTenantAuth();
const tenantId = await multiTenantAuth.determineTenant(req);
const tenantSlug = await multiTenantAuth.determineTenant(req);
if (!tenantId) {
return res.status(403).json({
if (!tenantSlug) {
return res.status(400).json({
success: false,
message: 'Access denied: No tenant context'
message: 'Unable to determine tenant'
});
}
const tenant = await Tenant.findOne({ where: { slug: tenantSlug } });
if (!tenant) {
return res.status(404).json({
success: false,
message: 'Tenant not found'
});
}
@@ -329,7 +365,7 @@ router.get('/charts/devices', authenticateToken, async (req, res) => {
include: [{
model: Device,
as: 'device',
where: { tenant_id: tenantId },
where: { tenant_id: tenant.id },
attributes: ['name', 'location_description']
}],
group: ['device_id', 'device.id', 'device.name', 'device.location_description'],