fix: hotbugs in multi-tenant arch.

This commit is contained in:
Ahmed Bouhuolia
2020-04-22 01:12:24 +02:00
parent 8f588ffc51
commit 1e13aa16ac
6 changed files with 33 additions and 80 deletions

13
server/cli/tenants.js Normal file
View File

@@ -0,0 +1,13 @@
import { program } from 'commander';
program
.version('0.0.1')
.description('An application for pizzas ordering')
.command('tenants:migrate')
.description('Migrate all tenants or the given tenant id.')
.option('-t, --tenant_id [tenant_id]', 'Which tenant id do you migrate.')
.action(async () => {
});
program.parse(process.argv);

View File

@@ -1,7 +1,7 @@
import fs from 'fs';
import path from 'path';
import TenantsManager from '@/system/TenantsManager';
import Model from '@/models/Model';
import TenantModel from '@/models/TenantModel';
function loadModelsFromDirectory() {
const models = {};
@@ -18,23 +18,29 @@ function loadModelsFromDirectory() {
}
export default async (req, res, next) => {
const { organization: organizationId } = req.query;
const notFoundOrganization = () => res.status(400).send({
errors: [{ type: 'ORGANIZATION.ID.NOT.FOUND' }],
});
const organizationId = req.headers['organization-id'] || req.query.organization;
const notFoundOrganization = () => res.boom.unauthorized(
'Organization identication not found.',
{ errors: [{ type: 'ORGANIZATION.ID.NOT.FOUND', code: 100 }] },
);
if (!organizationId) {
return notFoundOrganization();
}
const tenant = await TenantsManager.getTenant(organizationId);
// When the given organization id not found on the system storage.
if (!tenant) {
return notFoundOrganization();
}
// When user tenant not match the given organization id.
if (tenant.id !== req.user.tenantId) {
return res.boom.unauthorized();
}
const knex = TenantsManager.knexInstance(organizationId);
const models = loadModelsFromDirectory();
Model.knexBinded = knex;
TenantModel.knexBinded = knex;
req.knex = knex;
req.organizationId = organizationId;
@@ -42,7 +48,7 @@ export default async (req, res, next) => {
...Object.values(models).reduce((acc, model) => {
if (model.resource
&& model.resource.default
&& Object.getPrototypeOf(model.resource.default) === Model) {
&& Object.getPrototypeOf(model.resource.default) === TenantModel) {
acc[model.name] = model.resource.default.bindKnex(knex);
}
return acc;

View File

@@ -1,23 +1,14 @@
/* eslint-disable consistent-return */
import jwt from 'jsonwebtoken';
import SystemUser from '@/system/models/SystemUser';
// import Auth from '@/models/Auth';
const authMiddleware = (req, res, next) => {
const { JWT_SECRET_KEY } = process.env;
const token = req.headers['x-access-token'] || req.query.token;
const onError = () => {
// Auth.loggedOut();
res.status(401).send({
success: false,
message: 'unauthorized',
});
};
const onError = () => { res.boom.unauthorized(); };
if (!token) {
return onError();
}
if (!token) { return onError(); }
const verify = new Promise((resolve, reject) => {
jwt.verify(token, JWT_SECRET_KEY, async (error, decoded) => {
@@ -26,7 +17,6 @@ const authMiddleware = (req, res, next) => {
} else {
// eslint-disable-next-line no-underscore-dangle
req.user = await SystemUser.query().findById(decoded._id);
// Auth.setAuthenticatedUser(req.user);
if (!req.user) {
return onError();

View File

@@ -1,39 +0,0 @@
import { Model } from 'objection';
import TenantModel from '@/models/TenantModel';
export default class ItemMetadata extends TenantModel {
/**
* Table name
*/
static get tableName() {
return 'items_metadata';
}
/**
* Timestamp columns.
*/
static get hasTimestamps() {
return ['created_at', 'updated_at'];
}
/**
* Relationship mapping.
*/
static get relationMappings() {
const Item = require('@/models/Item');
return {
/**
* Item category may has many items.
*/
items: {
relation: Model.BelongsToOneRelation,
modelBase: this.relationBindKnex(Item.default),
join: {
from: 'items_metadata.item_id',
to: 'items.id',
},
},
};
}
}

View File

@@ -1,5 +1,3 @@
import { Model } from 'objection';
import path from 'path';
import TenantModel from '@/models/TenantModel';
import ResourceFieldMetadataCollection from '@/collection/ResourceFieldMetadataCollection';
@@ -17,23 +15,4 @@ export default class ResourceFieldMetadata extends TenantModel {
static get collection() {
return ResourceFieldMetadataCollection;
}
/**
* Relationship mapping.
*/
static get relationMappings() {
return {
/**
* Resource field may belongs to resource model.
*/
resource: {
relation: Model.BelongsToOneRelation,
modelBase: path.join(__dirname, 'Resource'),
join: {
from: 'resource_fields.resource_id',
to: 'resources.id',
},
},
};
}
}

View File

@@ -1,4 +1,5 @@
import Knex from 'knex';
import { knexSnakeCaseMappers } from 'objection';
import Tenant from '@/system/models/Tenant';
import config from '@/../config/config';
@@ -50,7 +51,10 @@ export default class TenantsManager {
let knex = knexCache.get(organizationId);
if (!knex) {
knex = Knex(this.getTenantKnexConfig(organizationId));
knex = Knex({
...this.getTenantKnexConfig(organizationId),
...knexSnakeCaseMappers({ upperCase: true }),
});
knexCache.set(organizationId, knex);
}
return knex;