Fix jwt-token
This commit is contained in:
191
server/tests/middleware/multi-tenant-auth.test.js
Normal file
191
server/tests/middleware/multi-tenant-auth.test.js
Normal file
@@ -0,0 +1,191 @@
|
||||
const { describe, it, beforeEach, afterEach, before, after } = require('mocha');
|
||||
const { expect } = require('chai');
|
||||
const sinon = require('sinon');
|
||||
const MultiTenantAuth = require('../../middleware/multi-tenant-auth');
|
||||
const { setupTestEnvironment, teardownTestEnvironment, cleanDatabase, mockRequest, mockResponse, mockNext, createTestUser, createTestTenant, generateTestToken } = require('../setup');
|
||||
|
||||
describe('Multi-Tenant Authentication Middleware', () => {
|
||||
let models, sequelize, multiAuth;
|
||||
|
||||
before(async () => {
|
||||
({ models, sequelize } = await setupTestEnvironment());
|
||||
multiAuth = new MultiTenantAuth();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await teardownTestEnvironment();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await cleanDatabase();
|
||||
});
|
||||
|
||||
describe('determineTenant', () => {
|
||||
it('should extract tenant from tenantId in JWT token', async () => {
|
||||
const tenant = await createTestTenant({ slug: 'test-tenant' });
|
||||
const user = await createTestUser({ tenant_id: tenant.id });
|
||||
|
||||
const req = mockRequest({
|
||||
user: { tenantId: tenant.slug }
|
||||
});
|
||||
|
||||
const result = await multiAuth.determineTenant(req);
|
||||
expect(result).to.equal(tenant.slug);
|
||||
});
|
||||
|
||||
it('should extract tenant from subdomain', async () => {
|
||||
const req = mockRequest({
|
||||
headers: { host: 'tenant1.example.com' }
|
||||
});
|
||||
|
||||
const result = await multiAuth.determineTenant(req);
|
||||
expect(result).to.equal('tenant1');
|
||||
});
|
||||
|
||||
it('should extract tenant from complex subdomain', async () => {
|
||||
const req = mockRequest({
|
||||
headers: { host: 'uamils-ab.dev.uggla.uamils.com' }
|
||||
});
|
||||
|
||||
const result = await multiAuth.determineTenant(req);
|
||||
expect(result).to.equal('uamils-ab');
|
||||
});
|
||||
|
||||
it('should extract tenant from domain path', async () => {
|
||||
const req = mockRequest({
|
||||
headers: { host: 'example.com' },
|
||||
url: '/tenant2/api/devices'
|
||||
});
|
||||
|
||||
const result = await multiAuth.determineTenant(req);
|
||||
expect(result).to.equal('tenant2');
|
||||
});
|
||||
|
||||
it('should prioritize JWT tenantId over subdomain', async () => {
|
||||
const req = mockRequest({
|
||||
user: { tenantId: 'jwt-tenant' },
|
||||
headers: { host: 'subdomain-tenant.example.com' }
|
||||
});
|
||||
|
||||
const result = await multiAuth.determineTenant(req);
|
||||
expect(result).to.equal('jwt-tenant');
|
||||
});
|
||||
|
||||
it('should return null for localhost without tenant info', async () => {
|
||||
const req = mockRequest({
|
||||
headers: { host: 'localhost:3000' }
|
||||
});
|
||||
|
||||
const result = await multiAuth.determineTenant(req);
|
||||
expect(result).to.be.null;
|
||||
});
|
||||
|
||||
it('should handle x-forwarded-host header', async () => {
|
||||
const req = mockRequest({
|
||||
headers: {
|
||||
host: 'localhost:3000',
|
||||
'x-forwarded-host': 'tenant3.example.com'
|
||||
}
|
||||
});
|
||||
|
||||
const result = await multiAuth.determineTenant(req);
|
||||
expect(result).to.equal('tenant3');
|
||||
});
|
||||
});
|
||||
|
||||
describe('middleware function', () => {
|
||||
it('should pass through when tenant is determined', async () => {
|
||||
const tenant = await createTestTenant({ slug: 'valid-tenant' });
|
||||
|
||||
const req = mockRequest({
|
||||
user: { tenantId: tenant.slug }
|
||||
});
|
||||
const res = mockResponse();
|
||||
const next = mockNext();
|
||||
|
||||
await multiAuth.middleware(req, res, next);
|
||||
|
||||
expect(req.tenant).to.equal(tenant.slug);
|
||||
expect(next.errors).to.have.length(0);
|
||||
});
|
||||
|
||||
it('should reject when tenant cannot be determined', async () => {
|
||||
const req = mockRequest({
|
||||
headers: { host: 'localhost:3000' }
|
||||
});
|
||||
const res = mockResponse();
|
||||
const next = mockNext();
|
||||
|
||||
await multiAuth.middleware(req, res, next);
|
||||
|
||||
expect(res.statusCode).to.equal(400);
|
||||
expect(res.data).to.deep.equal({
|
||||
success: false,
|
||||
message: 'Unable to determine tenant'
|
||||
});
|
||||
});
|
||||
|
||||
it('should reject when tenant does not exist in database', async () => {
|
||||
const req = mockRequest({
|
||||
user: { tenantId: 'nonexistent-tenant' }
|
||||
});
|
||||
const res = mockResponse();
|
||||
const next = mockNext();
|
||||
|
||||
await multiAuth.middleware(req, res, next);
|
||||
|
||||
expect(res.statusCode).to.equal(404);
|
||||
expect(res.data).to.deep.equal({
|
||||
success: false,
|
||||
message: 'Tenant not found'
|
||||
});
|
||||
});
|
||||
|
||||
it('should reject when tenant is inactive', async () => {
|
||||
const tenant = await createTestTenant({
|
||||
slug: 'inactive-tenant',
|
||||
is_active: false
|
||||
});
|
||||
|
||||
const req = mockRequest({
|
||||
user: { tenantId: tenant.slug }
|
||||
});
|
||||
const res = mockResponse();
|
||||
const next = mockNext();
|
||||
|
||||
await multiAuth.middleware(req, res, next);
|
||||
|
||||
expect(res.statusCode).to.equal(403);
|
||||
expect(res.data).to.deep.equal({
|
||||
success: false,
|
||||
message: 'Tenant is not active'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('validateTenantAccess', () => {
|
||||
it('should validate user belongs to tenant', async () => {
|
||||
const tenant = await createTestTenant({ slug: 'user-tenant' });
|
||||
const user = await createTestUser({ tenant_id: tenant.id });
|
||||
|
||||
const isValid = await multiAuth.validateTenantAccess(user.id, tenant.slug);
|
||||
expect(isValid).to.be.true;
|
||||
});
|
||||
|
||||
it('should reject user from different tenant', async () => {
|
||||
const tenant1 = await createTestTenant({ slug: 'tenant1' });
|
||||
const tenant2 = await createTestTenant({ slug: 'tenant2' });
|
||||
const user = await createTestUser({ tenant_id: tenant1.id });
|
||||
|
||||
const isValid = await multiAuth.validateTenantAccess(user.id, tenant2.slug);
|
||||
expect(isValid).to.be.false;
|
||||
});
|
||||
|
||||
it('should reject nonexistent user', async () => {
|
||||
const tenant = await createTestTenant({ slug: 'valid-tenant' });
|
||||
|
||||
const isValid = await multiAuth.validateTenantAccess(99999, tenant.slug);
|
||||
expect(isValid).to.be.false;
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user