Fix jwt-token
This commit is contained in:
@@ -279,6 +279,33 @@ class MultiTenantAuth {
|
|||||||
{ expiresIn: '24h' }
|
{ 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;
|
module.exports = MultiTenantAuth;
|
||||||
|
|||||||
@@ -35,12 +35,20 @@ router.get('/rules', authenticateToken, async (req, res) => {
|
|||||||
|
|
||||||
// Initialize multi-tenant auth to determine tenant
|
// Initialize multi-tenant auth to determine tenant
|
||||||
const multiTenantAuth = new MultiTenantAuth();
|
const multiTenantAuth = new MultiTenantAuth();
|
||||||
const tenantId = await multiTenantAuth.determineTenant(req);
|
const tenantSlug = await multiTenantAuth.determineTenant(req);
|
||||||
|
|
||||||
if (!tenantId) {
|
if (!tenantSlug) {
|
||||||
return res.status(403).json({
|
return res.status(400).json({
|
||||||
success: false,
|
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: [{
|
include: [{
|
||||||
model: User,
|
model: User,
|
||||||
as: 'user',
|
as: 'user',
|
||||||
where: { tenant_id: tenantId },
|
where: { tenant_id: tenant.id },
|
||||||
attributes: ['id', 'username', 'email']
|
attributes: ['id', 'username', 'email']
|
||||||
}],
|
}],
|
||||||
limit: Math.min(parseInt(limit), 100),
|
limit: Math.min(parseInt(limit), 100),
|
||||||
@@ -126,12 +134,20 @@ router.put('/rules/:id', authenticateToken, validateRequest(alertRuleSchema), as
|
|||||||
try {
|
try {
|
||||||
// Initialize multi-tenant auth to determine tenant
|
// Initialize multi-tenant auth to determine tenant
|
||||||
const multiTenantAuth = new MultiTenantAuth();
|
const multiTenantAuth = new MultiTenantAuth();
|
||||||
const tenantId = await multiTenantAuth.determineTenant(req);
|
const tenantSlug = await multiTenantAuth.determineTenant(req);
|
||||||
|
|
||||||
if (!tenantId) {
|
if (!tenantSlug) {
|
||||||
return res.status(403).json({
|
return res.status(400).json({
|
||||||
success: false,
|
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: [{
|
include: [{
|
||||||
model: User,
|
model: User,
|
||||||
as: 'user',
|
as: 'user',
|
||||||
where: { tenant_id: tenantId },
|
where: { tenant_id: tenant.id },
|
||||||
attributes: ['id']
|
attributes: ['id']
|
||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
@@ -177,12 +193,20 @@ router.delete('/rules/:id', authenticateToken, async (req, res) => {
|
|||||||
try {
|
try {
|
||||||
// Initialize multi-tenant auth to determine tenant
|
// Initialize multi-tenant auth to determine tenant
|
||||||
const multiTenantAuth = new MultiTenantAuth();
|
const multiTenantAuth = new MultiTenantAuth();
|
||||||
const tenantId = await multiTenantAuth.determineTenant(req);
|
const tenantSlug = await multiTenantAuth.determineTenant(req);
|
||||||
|
|
||||||
if (!tenantId) {
|
if (!tenantSlug) {
|
||||||
return res.status(403).json({
|
return res.status(400).json({
|
||||||
success: false,
|
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: [{
|
include: [{
|
||||||
model: User,
|
model: User,
|
||||||
as: 'user',
|
as: 'user',
|
||||||
where: { tenant_id: tenantId },
|
where: { tenant_id: tenant.id },
|
||||||
attributes: ['id']
|
attributes: ['id']
|
||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
@@ -236,12 +260,20 @@ router.get('/logs', authenticateToken, async (req, res) => {
|
|||||||
|
|
||||||
// Initialize multi-tenant auth to determine tenant
|
// Initialize multi-tenant auth to determine tenant
|
||||||
const multiTenantAuth = new MultiTenantAuth();
|
const multiTenantAuth = new MultiTenantAuth();
|
||||||
const tenantId = await multiTenantAuth.determineTenant(req);
|
const tenantSlug = await multiTenantAuth.determineTenant(req);
|
||||||
|
|
||||||
if (!tenantId) {
|
if (!tenantSlug) {
|
||||||
return res.status(403).json({
|
return res.status(400).json({
|
||||||
success: false,
|
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: [{
|
include: [{
|
||||||
model: User,
|
model: User,
|
||||||
as: 'user',
|
as: 'user',
|
||||||
where: { tenant_id: tenantId },
|
where: { tenant_id: tenant.id },
|
||||||
attributes: ['id', 'username']
|
attributes: ['id', 'username']
|
||||||
}],
|
}],
|
||||||
attributes: ['id', 'name', 'priority']
|
attributes: ['id', 'name', 'priority']
|
||||||
@@ -302,12 +334,20 @@ router.get('/stats', authenticateToken, async (req, res) => {
|
|||||||
|
|
||||||
// Initialize multi-tenant auth to determine tenant
|
// Initialize multi-tenant auth to determine tenant
|
||||||
const multiTenantAuth = new MultiTenantAuth();
|
const multiTenantAuth = new MultiTenantAuth();
|
||||||
const tenantId = await multiTenantAuth.determineTenant(req);
|
const tenantSlug = await multiTenantAuth.determineTenant(req);
|
||||||
|
|
||||||
if (!tenantId) {
|
if (!tenantSlug) {
|
||||||
return res.status(403).json({
|
return res.status(400).json({
|
||||||
success: false,
|
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: [{
|
include: [{
|
||||||
model: User,
|
model: User,
|
||||||
as: 'user',
|
as: 'user',
|
||||||
where: { tenant_id: tenantId },
|
where: { tenant_id: tenant.id },
|
||||||
attributes: []
|
attributes: []
|
||||||
}],
|
}],
|
||||||
attributes: ['id']
|
attributes: ['id']
|
||||||
|
|||||||
@@ -14,17 +14,25 @@ router.get('/overview', authenticateToken, async (req, res) => {
|
|||||||
|
|
||||||
// Initialize multi-tenant auth to determine tenant
|
// Initialize multi-tenant auth to determine tenant
|
||||||
const multiTenantAuth = new MultiTenantAuth();
|
const multiTenantAuth = new MultiTenantAuth();
|
||||||
const tenantId = await multiTenantAuth.determineTenant(req);
|
const tenantSlug = await multiTenantAuth.determineTenant(req);
|
||||||
|
|
||||||
if (!tenantId) {
|
if (!tenantSlug) {
|
||||||
return res.status(403).json({
|
return res.status(400).json({
|
||||||
success: false,
|
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
|
// Create base filter for tenant devices
|
||||||
const tenantDeviceFilter = { tenant_id: tenantId };
|
const tenantDeviceFilter = { tenant_id: tenant.id };
|
||||||
|
|
||||||
// Get basic statistics - filtered by tenant
|
// Get basic statistics - filtered by tenant
|
||||||
const [
|
const [
|
||||||
@@ -39,6 +47,7 @@ router.get('/overview', authenticateToken, async (req, res) => {
|
|||||||
DroneDetection.count({
|
DroneDetection.count({
|
||||||
include: [{
|
include: [{
|
||||||
model: Device,
|
model: Device,
|
||||||
|
as: 'device',
|
||||||
where: tenantDeviceFilter,
|
where: tenantDeviceFilter,
|
||||||
attributes: []
|
attributes: []
|
||||||
}],
|
}],
|
||||||
@@ -47,6 +56,7 @@ router.get('/overview', authenticateToken, async (req, res) => {
|
|||||||
DroneDetection.count({
|
DroneDetection.count({
|
||||||
include: [{
|
include: [{
|
||||||
model: Device,
|
model: Device,
|
||||||
|
as: 'device',
|
||||||
where: tenantDeviceFilter,
|
where: tenantDeviceFilter,
|
||||||
attributes: []
|
attributes: []
|
||||||
}],
|
}],
|
||||||
@@ -58,6 +68,7 @@ router.get('/overview', authenticateToken, async (req, res) => {
|
|||||||
DroneDetection.count({
|
DroneDetection.count({
|
||||||
include: [{
|
include: [{
|
||||||
model: Device,
|
model: Device,
|
||||||
|
as: 'device',
|
||||||
where: tenantDeviceFilter,
|
where: tenantDeviceFilter,
|
||||||
attributes: []
|
attributes: []
|
||||||
}],
|
}],
|
||||||
@@ -145,12 +156,20 @@ router.get('/activity', authenticateToken, async (req, res) => {
|
|||||||
|
|
||||||
// Initialize multi-tenant auth to determine tenant
|
// Initialize multi-tenant auth to determine tenant
|
||||||
const multiTenantAuth = new MultiTenantAuth();
|
const multiTenantAuth = new MultiTenantAuth();
|
||||||
const tenantId = await multiTenantAuth.determineTenant(req);
|
const tenantSlug = await multiTenantAuth.determineTenant(req);
|
||||||
|
|
||||||
if (!tenantId) {
|
if (!tenantSlug) {
|
||||||
return res.status(403).json({
|
return res.status(400).json({
|
||||||
success: false,
|
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: [{
|
include: [{
|
||||||
model: Device,
|
model: Device,
|
||||||
as: 'device',
|
as: 'device',
|
||||||
where: { tenant_id: tenantId },
|
where: { tenant_id: tenant.id },
|
||||||
attributes: ['id', 'name', 'geo_lat', 'geo_lon', 'location_description']
|
attributes: ['id', 'name', 'geo_lat', 'geo_lon', 'location_description']
|
||||||
}],
|
}],
|
||||||
limit: Math.min(parseInt(limit), 200),
|
limit: Math.min(parseInt(limit), 200),
|
||||||
@@ -176,7 +195,7 @@ router.get('/activity', authenticateToken, async (req, res) => {
|
|||||||
include: [{
|
include: [{
|
||||||
model: Device,
|
model: Device,
|
||||||
as: 'device',
|
as: 'device',
|
||||||
where: { tenant_id: tenantId },
|
where: { tenant_id: tenant.id },
|
||||||
attributes: ['id', 'name', 'geo_lat', 'geo_lon']
|
attributes: ['id', 'name', 'geo_lat', 'geo_lon']
|
||||||
}],
|
}],
|
||||||
limit: Math.min(parseInt(limit), 50),
|
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
|
// Initialize multi-tenant auth to determine tenant
|
||||||
const multiTenantAuth = new MultiTenantAuth();
|
const multiTenantAuth = new MultiTenantAuth();
|
||||||
const tenantId = await multiTenantAuth.determineTenant(req);
|
const tenantSlug = await multiTenantAuth.determineTenant(req);
|
||||||
|
|
||||||
if (!tenantId) {
|
if (!tenantSlug) {
|
||||||
return res.status(403).json({
|
return res.status(400).json({
|
||||||
success: false,
|
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({
|
const detectionCounts = await DroneDetection.findAll({
|
||||||
include: [{
|
include: [{
|
||||||
model: Device,
|
model: Device,
|
||||||
where: { tenant_id: tenantId },
|
as: 'device',
|
||||||
|
where: { tenant_id: tenant.id },
|
||||||
attributes: []
|
attributes: []
|
||||||
}],
|
}],
|
||||||
where: {
|
where: {
|
||||||
@@ -308,12 +336,20 @@ router.get('/charts/devices', authenticateToken, async (req, res) => {
|
|||||||
|
|
||||||
// Initialize multi-tenant auth to determine tenant
|
// Initialize multi-tenant auth to determine tenant
|
||||||
const multiTenantAuth = new MultiTenantAuth();
|
const multiTenantAuth = new MultiTenantAuth();
|
||||||
const tenantId = await multiTenantAuth.determineTenant(req);
|
const tenantSlug = await multiTenantAuth.determineTenant(req);
|
||||||
|
|
||||||
if (!tenantId) {
|
if (!tenantSlug) {
|
||||||
return res.status(403).json({
|
return res.status(400).json({
|
||||||
success: false,
|
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: [{
|
include: [{
|
||||||
model: Device,
|
model: Device,
|
||||||
as: 'device',
|
as: 'device',
|
||||||
where: { tenant_id: tenantId },
|
where: { tenant_id: tenant.id },
|
||||||
attributes: ['name', 'location_description']
|
attributes: ['name', 'location_description']
|
||||||
}],
|
}],
|
||||||
group: ['device_id', 'device.id', 'device.name', 'device.location_description'],
|
group: ['device_id', 'device.id', 'device.name', 'device.location_description'],
|
||||||
|
|||||||
Reference in New Issue
Block a user