@volcanicminds/typeorm 2.3.1 → 2.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -2
- package/dist/index.js.map +1 -1
- package/dist/lib/entities/tenant.d.ts +13 -0
- package/dist/lib/entities/tenant.d.ts.map +1 -0
- package/dist/lib/entities/tenant.js +4 -0
- package/dist/lib/entities/tenant.js.map +1 -0
- package/dist/lib/loader/tenantManager.d.ts +12 -0
- package/dist/lib/loader/tenantManager.d.ts.map +1 -0
- package/dist/lib/loader/tenantManager.js +80 -0
- package/dist/lib/loader/tenantManager.js.map +1 -0
- package/lib/entities/tenant.ts +20 -0
- package/lib/loader/tenantManager.ts +110 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -3,11 +3,13 @@ import { DataSource } from 'typeorm';
|
|
|
3
3
|
import * as userManager from './lib/loader/userManager.js';
|
|
4
4
|
import * as tokenManager from './lib/loader/tokenManager.js';
|
|
5
5
|
import * as dataBaseManager from './lib/loader/dataBaseManager.js';
|
|
6
|
+
import { TenantManager } from './lib/loader/tenantManager.js';
|
|
6
7
|
import { User } from './lib/entities/user.js';
|
|
8
|
+
import { Tenant } from './lib/entities/tenant.js';
|
|
7
9
|
import { Token } from './lib/entities/token.js';
|
|
8
10
|
import { Change } from './lib/entities/change.js';
|
|
9
11
|
import { applyQuery, executeCountQuery, executeCountView, executeFindQuery, executeFindView, useOrder, useWhere, configureSensitiveFields } from './lib/query.js';
|
|
10
12
|
declare function start(options: any): Promise<DataSource>;
|
|
11
13
|
export { Database } from './types/global.js';
|
|
12
|
-
export { start, User, Token, Change, userManager, tokenManager, dataBaseManager, DataSource, applyQuery, executeCountQuery, executeCountView, executeFindQuery, executeFindView, useOrder, useWhere, configureSensitiveFields };
|
|
14
|
+
export { start, User, Tenant, Token, Change, userManager, tokenManager, dataBaseManager, TenantManager, DataSource, applyQuery, executeCountQuery, executeCountView, executeFindQuery, executeFindView, useOrder, useWhere, configureSensitiveFields };
|
|
13
15
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAIA,OAAO,kBAAkB,CAAA;AACzB,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEpC,OAAO,KAAK,WAAW,MAAM,6BAA6B,CAAA;AAC1D,OAAO,KAAK,YAAY,MAAM,8BAA8B,CAAA;AAC5D,OAAO,KAAK,eAAe,MAAM,iCAAiC,CAAA;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAA;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAA;AACjD,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,QAAQ,EACR,QAAQ,EACR,wBAAwB,EACzB,MAAM,gBAAgB,CAAA;AAIvB,iBAAe,KAAK,CAAC,OAAO,KAAA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAIA,OAAO,kBAAkB,CAAA;AACzB,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEpC,OAAO,KAAK,WAAW,MAAM,6BAA6B,CAAA;AAC1D,OAAO,KAAK,YAAY,MAAM,8BAA8B,CAAA;AAC5D,OAAO,KAAK,eAAe,MAAM,iCAAiC,CAAA;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AAC7D,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAA;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAA;AACjD,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAA;AACjD,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,QAAQ,EACR,QAAQ,EACR,wBAAwB,EACzB,MAAM,gBAAgB,CAAA;AAIvB,iBAAe,KAAK,CAAC,OAAO,KAAA,uBA8E3B;AAED,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC5C,OAAO,EACL,KAAK,EACL,IAAI,EACJ,MAAM,EACN,KAAK,EACL,MAAM,EACN,WAAW,EACX,YAAY,EACZ,eAAe,EACf,aAAa,EACb,UAAU,EACV,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,QAAQ,EACR,QAAQ,EACR,wBAAwB,EACzB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,9 @@ import * as loaderEntities from './lib/loader/entities.js';
|
|
|
6
6
|
import * as userManager from './lib/loader/userManager.js';
|
|
7
7
|
import * as tokenManager from './lib/loader/tokenManager.js';
|
|
8
8
|
import * as dataBaseManager from './lib/loader/dataBaseManager.js';
|
|
9
|
+
import { TenantManager } from './lib/loader/tenantManager.js';
|
|
9
10
|
import { User } from './lib/entities/user.js';
|
|
11
|
+
import { Tenant } from './lib/entities/tenant.js';
|
|
10
12
|
import { Token } from './lib/entities/token.js';
|
|
11
13
|
import { Change } from './lib/entities/change.js';
|
|
12
14
|
import { applyQuery, executeCountQuery, executeCountView, executeFindQuery, executeFindView, useOrder, useWhere, configureSensitiveFields } from './lib/query.js';
|
|
@@ -62,8 +64,17 @@ async function start(options) {
|
|
|
62
64
|
Object.keys(repositories).map((r) => (repository[r] = ds.getRepository(repositories[r])));
|
|
63
65
|
global.connection = ds;
|
|
64
66
|
global.entity = classes;
|
|
65
|
-
global.repository = repository
|
|
67
|
+
global.repository = new Proxy(repository, {
|
|
68
|
+
get(target, prop) {
|
|
69
|
+
if (prop === 'toJSON' || prop === 'toString' || prop === Symbol.toStringTag)
|
|
70
|
+
return target[prop];
|
|
71
|
+
if (typeof prop === 'string' && prop in target) {
|
|
72
|
+
throw new Error(`[Volcanic Architecture 2.0] FATAL: Access to global.repository.${prop} is FORBIDDEN. Refactor usage to Context-Aware Service: service.use(req.db).`);
|
|
73
|
+
}
|
|
74
|
+
return target[prop];
|
|
75
|
+
}
|
|
76
|
+
});
|
|
66
77
|
return ds;
|
|
67
78
|
}
|
|
68
|
-
export { start, User, Token, Change, userManager, tokenManager, dataBaseManager, DataSource, applyQuery, executeCountQuery, executeCountView, executeFindQuery, executeFindView, useOrder, useWhere, configureSensitiveFields };
|
|
79
|
+
export { start, User, Tenant, Token, Change, userManager, tokenManager, dataBaseManager, TenantManager, DataSource, applyQuery, executeCountQuery, executeCountView, executeFindQuery, executeFindView, useOrder, useWhere, configureSensitiveFields };
|
|
69
80
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,QAAQ,CAAA;AAC3B,MAAM,CAAC,MAAM,EAAE,CAAA;AAEf,OAAO,kBAAkB,CAAA;AACzB,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,KAAK,cAAc,MAAM,0BAA0B,CAAA;AAC1D,OAAO,KAAK,WAAW,MAAM,6BAA6B,CAAA;AAC1D,OAAO,KAAK,YAAY,MAAM,8BAA8B,CAAA;AAC5D,OAAO,KAAK,eAAe,MAAM,iCAAiC,CAAA;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAA;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAA;AACjD,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,QAAQ,EACR,QAAQ,EACR,wBAAwB,EACzB,MAAM,gBAAgB,CAAA;AACvB,OAAO,KAAK,GAAG,MAAM,sBAAsB,CAAA;AAC3C,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAEjC,KAAK,UAAU,KAAK,CAAC,OAAO;IAC1B,IAAK,MAAc,CAAC,qBAAqB,EAAE,CAAC;QAC1C,OAAO,GAAG;YACR,IAAI,EAAE,UAAU;YAChB,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE,IAAI;YACV,QAAQ,EAAE,QAAQ;YAClB,QAAQ,EAAE,QAAQ;YAClB,QAAQ,EAAE,QAAQ;YAClB,WAAW,EAAE,IAAI;YACjB,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,EAAE;SACX,CAAA;IACH,CAAC;IAED,IAAI,OAAO,IAAI,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAA;IAC7D,CAAC;IAED,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;QAC5B,wBAAwB,CAAC,OAAO,CAAC,eAAe,CAAC,CAAA;IACnD,CAAC;IAED,MAAM,EAAE,YAAY,GAAG,MAAM,EAAE,YAAY,GAAG,IAAI,EAAE,gCAAgC,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC,GAAG,CAAA;IAE5G,MAAM,QAAQ,GACZ,YAAY,KAAK,OAAO;QACtB,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,YAAY,KAAK,OAAO;YAC1B,CAAC,CAAC,OAAO;YACT,CAAC,CAAC,YAAY,KAAK,MAAM;gBACzB,CAAC,CAAC,MAAM;gBACR,CAAC,CAAC,YAAY,KAAK,MAAM;oBACzB,CAAC,CAAC,MAAM;oBACR,CAAC,CAAC,YAAY,KAAK,OAAO;wBAC1B,CAAC,CAAC,OAAO;wBACT,CAAC,CAAC,YAAY,CAEjB;IAAC,MAAc,CAAC,YAAY,GAAG,OAAO,EAAE,YAAY,IAAI,KAAK,CAC7D;IAAC,MAAc,CAAC,gBAAgB,GAAG,OAAO,EAAE,OAAO,IAAI,IAAI,CAAA;IAE5D,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,CAAA;IACvE,OAAO,CAAC,QAAQ,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAA;IACrE,OAAO,CAAC,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,gBAAgB,CAAA;IACrE,OAAO,CAAC,OAAO,GAAG,QAAQ,CAAA;IAC1B,OAAO,CAAC,WAAW,GAAG,KAAK,CAAA;IAE3B,MAAM,EAAE,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,CAAA;IAClC,MAAM,EAAE,CAAC,UAAU,EAAE,CAAA;IAErB,IAAI,EAAE,CAAC,gCAAgC,EAAE,KAAK,CAAC,EAAE,CAAC;QAChD,GAAG,CAAC,IAAI,CAAC,2DAA2D,CAAC,CAAA;QACrE,MAAM,EAAE,CAAC,WAAW,EAAE,CAAA;QACtB,GAAG,CAAC,IAAI,CAAC,4DAA4D,CAAC,CAAA;IACxE,CAAC;IAGD,MAAM,UAAU,GAAG,EAAE,CAAA;IACrB,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CACxF;IAAC,MAAc,CAAC,UAAU,GAAG,EAAE,CAC/B;IAAC,MAAc,CAAC,MAAM,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,QAAQ,CAAA;AAC3B,MAAM,CAAC,MAAM,EAAE,CAAA;AAEf,OAAO,kBAAkB,CAAA;AACzB,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,KAAK,cAAc,MAAM,0BAA0B,CAAA;AAC1D,OAAO,KAAK,WAAW,MAAM,6BAA6B,CAAA;AAC1D,OAAO,KAAK,YAAY,MAAM,8BAA8B,CAAA;AAC5D,OAAO,KAAK,eAAe,MAAM,iCAAiC,CAAA;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AAC7D,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAA;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAA;AACjD,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAA;AACjD,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,QAAQ,EACR,QAAQ,EACR,wBAAwB,EACzB,MAAM,gBAAgB,CAAA;AACvB,OAAO,KAAK,GAAG,MAAM,sBAAsB,CAAA;AAC3C,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAEjC,KAAK,UAAU,KAAK,CAAC,OAAO;IAC1B,IAAK,MAAc,CAAC,qBAAqB,EAAE,CAAC;QAC1C,OAAO,GAAG;YACR,IAAI,EAAE,UAAU;YAChB,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE,IAAI;YACV,QAAQ,EAAE,QAAQ;YAClB,QAAQ,EAAE,QAAQ;YAClB,QAAQ,EAAE,QAAQ;YAClB,WAAW,EAAE,IAAI;YACjB,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,EAAE;SACX,CAAA;IACH,CAAC;IAED,IAAI,OAAO,IAAI,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAA;IAC7D,CAAC;IAED,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;QAC5B,wBAAwB,CAAC,OAAO,CAAC,eAAe,CAAC,CAAA;IACnD,CAAC;IAED,MAAM,EAAE,YAAY,GAAG,MAAM,EAAE,YAAY,GAAG,IAAI,EAAE,gCAAgC,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC,GAAG,CAAA;IAE5G,MAAM,QAAQ,GACZ,YAAY,KAAK,OAAO;QACtB,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,YAAY,KAAK,OAAO;YAC1B,CAAC,CAAC,OAAO;YACT,CAAC,CAAC,YAAY,KAAK,MAAM;gBACzB,CAAC,CAAC,MAAM;gBACR,CAAC,CAAC,YAAY,KAAK,MAAM;oBACzB,CAAC,CAAC,MAAM;oBACR,CAAC,CAAC,YAAY,KAAK,OAAO;wBAC1B,CAAC,CAAC,OAAO;wBACT,CAAC,CAAC,YAAY,CAEjB;IAAC,MAAc,CAAC,YAAY,GAAG,OAAO,EAAE,YAAY,IAAI,KAAK,CAC7D;IAAC,MAAc,CAAC,gBAAgB,GAAG,OAAO,EAAE,OAAO,IAAI,IAAI,CAAA;IAE5D,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,CAAA;IACvE,OAAO,CAAC,QAAQ,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAA;IACrE,OAAO,CAAC,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,gBAAgB,CAAA;IACrE,OAAO,CAAC,OAAO,GAAG,QAAQ,CAAA;IAC1B,OAAO,CAAC,WAAW,GAAG,KAAK,CAAA;IAE3B,MAAM,EAAE,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,CAAA;IAClC,MAAM,EAAE,CAAC,UAAU,EAAE,CAAA;IAErB,IAAI,EAAE,CAAC,gCAAgC,EAAE,KAAK,CAAC,EAAE,CAAC;QAChD,GAAG,CAAC,IAAI,CAAC,2DAA2D,CAAC,CAAA;QACrE,MAAM,EAAE,CAAC,WAAW,EAAE,CAAA;QACtB,GAAG,CAAC,IAAI,CAAC,4DAA4D,CAAC,CAAA;IACxE,CAAC;IAGD,MAAM,UAAU,GAAG,EAAE,CAAA;IACrB,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CACxF;IAAC,MAAc,CAAC,UAAU,GAAG,EAAE,CAC/B;IAAC,MAAc,CAAC,MAAM,GAAG,OAAO,CAGhC;IAAC,MAAc,CAAC,UAAU,GAAG,IAAI,KAAK,CAAC,UAAU,EAAE;QAClD,GAAG,CAAC,MAAM,EAAE,IAAI;YAEd,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,UAAU,IAAI,IAAI,KAAK,MAAM,CAAC,WAAW;gBAAE,OAAO,MAAM,CAAC,IAAI,CAAC,CAAA;YAGhG,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;gBAC/C,MAAM,IAAI,KAAK,CAAC,kEAAkE,IAAI,8EAA8E,CAAC,CAAA;YACvK,CAAC;YAED,OAAO,MAAM,CAAC,IAAI,CAAC,CAAA;QACrB,CAAC;KACF,CAAC,CAAA;IAEF,OAAO,EAAE,CAAA;AACX,CAAC;AAGD,OAAO,EACL,KAAK,EACL,IAAI,EACJ,MAAM,EACN,KAAK,EACL,MAAM,EACN,WAAW,EACX,YAAY,EACZ,eAAe,EACf,aAAa,EACb,UAAU,EACV,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,QAAQ,EACR,QAAQ,EACR,wBAAwB,EACzB,CAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BaseEntity } from 'typeorm';
|
|
2
|
+
export declare abstract class Tenant extends BaseEntity {
|
|
3
|
+
abstract id: any;
|
|
4
|
+
abstract name: string;
|
|
5
|
+
abstract slug: string;
|
|
6
|
+
abstract dbSchema?: string;
|
|
7
|
+
abstract dbName?: string;
|
|
8
|
+
abstract status: 'active' | 'suspended' | 'archived';
|
|
9
|
+
abstract createdAt: Date;
|
|
10
|
+
abstract updatedAt: Date;
|
|
11
|
+
abstract getConfig(): Record<string, any>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=tenant.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant.d.ts","sourceRoot":"","sources":["../../../lib/entities/tenant.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEpC,8BAAsB,MAAO,SAAQ,UAAU;IAC7C,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAA;IAChB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IAGrB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IAExB,QAAQ,CAAC,MAAM,EAAE,QAAQ,GAAG,WAAW,GAAG,UAAU,CAAA;IAEpD,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAA;IACxB,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAA;IAGxB,QAAQ,CAAC,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;CAC1C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant.js","sourceRoot":"","sources":["../../../lib/entities/tenant.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEpC,MAAM,OAAgB,MAAO,SAAQ,UAAU;CAgB9C"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { DataSource, EntityManager } from 'typeorm';
|
|
2
|
+
import { Tenant } from '../entities/tenant.js';
|
|
3
|
+
export declare class TenantManager {
|
|
4
|
+
private dataSource;
|
|
5
|
+
constructor(dataSource: DataSource);
|
|
6
|
+
isImplemented(): boolean;
|
|
7
|
+
resolveTenant(req: any): Promise<Tenant | null>;
|
|
8
|
+
switchContext(tenant: Tenant, db?: EntityManager): Promise<void>;
|
|
9
|
+
createTenant(data: any): Promise<void>;
|
|
10
|
+
deleteTenant(_id: string): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=tenantManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenantManager.d.ts","sourceRoot":"","sources":["../../../lib/loader/tenantManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAE9C,qBAAa,aAAa;IACZ,OAAO,CAAC,UAAU;gBAAV,UAAU,EAAE,UAAU;IAE1C,aAAa;IAIP,aAAa,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAyD/C,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,aAAa;IAqBhD,YAAY,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBtC,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAI/C"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { Tenant } from '../entities/tenant.js';
|
|
2
|
+
export class TenantManager {
|
|
3
|
+
dataSource;
|
|
4
|
+
constructor(dataSource) {
|
|
5
|
+
this.dataSource = dataSource;
|
|
6
|
+
}
|
|
7
|
+
isImplemented() {
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
async resolveTenant(req) {
|
|
11
|
+
const { multi_tenant } = global.config?.options || {};
|
|
12
|
+
if (!multi_tenant?.enabled) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
const jwtTid = req.user?.tid;
|
|
16
|
+
const headerTid = req.headers['x-tenant-id'];
|
|
17
|
+
if (!headerTid) {
|
|
18
|
+
throw new Error('Multi-Tenancy Error: Missing x-tenant-id header');
|
|
19
|
+
}
|
|
20
|
+
if (jwtTid && headerTid) {
|
|
21
|
+
if (jwtTid !== headerTid) {
|
|
22
|
+
throw new Error('Security Alert: JWT Tenant ID mismatch with Header Tenant ID');
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
const tenantId = headerTid || jwtTid;
|
|
26
|
+
if (!tenantId) {
|
|
27
|
+
if (global.log?.d)
|
|
28
|
+
global.log.debug('[TenantManager] No tenant ID found in request');
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
const tenantRepo = this.dataSource.getRepository(Tenant);
|
|
32
|
+
const tenant = await tenantRepo.findOne({ where: { id: tenantId } });
|
|
33
|
+
if (!tenant) {
|
|
34
|
+
if (global.log?.w)
|
|
35
|
+
global.log.warn(`[TenantManager] Tenant ${tenantId} not found in DB`);
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
return tenant;
|
|
39
|
+
}
|
|
40
|
+
async switchContext(tenant, db) {
|
|
41
|
+
const driver = this.dataSource.driver.options.type;
|
|
42
|
+
if (driver === 'postgres') {
|
|
43
|
+
const schema = tenant.dbSchema || 'public';
|
|
44
|
+
const safeSchema = schema.replace(/[^a-z0-9_]/gi, '');
|
|
45
|
+
if (db) {
|
|
46
|
+
if (global.log?.t)
|
|
47
|
+
global.log.trace(`[TenantManager] Context-Aware Switch Schema to: ${safeSchema}`);
|
|
48
|
+
await db.query(`SET search_path TO "${safeSchema}", public`);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
if (global.log?.w)
|
|
52
|
+
global.log.warn('[TenantManager] ⚠️ Switching Global Connection Pool Context! Use generic .use(req.db) pattern instead.');
|
|
53
|
+
await this.dataSource.query(`SET search_path TO "${safeSchema}", public`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
else if (driver === 'mongodb') {
|
|
57
|
+
if (global.log?.w)
|
|
58
|
+
global.log.warn('[TenantManager] Mongo Multi-Tenancy context switch is not enforcing isolation yet.');
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async createTenant(data) {
|
|
62
|
+
const driver = this.dataSource.driver.options.type;
|
|
63
|
+
if (driver === 'postgres') {
|
|
64
|
+
const schema = data.dbSchema;
|
|
65
|
+
if (!schema)
|
|
66
|
+
throw new Error('dbSchema is required for Postgres Multi-Tenancy');
|
|
67
|
+
const safeSchema = schema.replace(/[^a-z0-9_]/gi, '');
|
|
68
|
+
await this.dataSource.query(`CREATE SCHEMA IF NOT EXISTS "${safeSchema}"`);
|
|
69
|
+
if (global.log?.i)
|
|
70
|
+
global.log.info(`[TenantManager] Created Schema: ${safeSchema}`);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
throw new Error(`createTenant not implemented for driver: ${driver}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async deleteTenant(_id) {
|
|
77
|
+
throw new Error('deleteTenant requires full implementation with Safety Checks (Drop Schema is dangerous)');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=tenantManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenantManager.js","sourceRoot":"","sources":["../../../lib/loader/tenantManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import { BaseEntity } from 'typeorm'
|
|
3
|
+
|
|
4
|
+
export abstract class Tenant extends BaseEntity {
|
|
5
|
+
abstract id: any
|
|
6
|
+
abstract name: string
|
|
7
|
+
abstract slug: string
|
|
8
|
+
|
|
9
|
+
// Campi specifici per strategia
|
|
10
|
+
abstract dbSchema?: string // Per Postgres (schema splitting)
|
|
11
|
+
abstract dbName?: string // Per Mongo (database splitting, opzionale)
|
|
12
|
+
|
|
13
|
+
abstract status: 'active' | 'suspended' | 'archived'
|
|
14
|
+
|
|
15
|
+
abstract createdAt: Date
|
|
16
|
+
abstract updatedAt: Date
|
|
17
|
+
|
|
18
|
+
// Configurazione opzionale
|
|
19
|
+
abstract getConfig(): Record<string, any>
|
|
20
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import { DataSource, EntityManager } from 'typeorm'
|
|
3
|
+
import { Tenant } from '../entities/tenant.js'
|
|
4
|
+
|
|
5
|
+
export class TenantManager {
|
|
6
|
+
constructor(private dataSource: DataSource) {}
|
|
7
|
+
|
|
8
|
+
isImplemented() {
|
|
9
|
+
return true
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async resolveTenant(req: any): Promise<Tenant | null> {
|
|
13
|
+
const { multi_tenant } = (global as any).config?.options || {}
|
|
14
|
+
|
|
15
|
+
// 1. Single Tenant Mode (Default)
|
|
16
|
+
if (!multi_tenant?.enabled) {
|
|
17
|
+
return null
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// 2. Multi-Tenant Mode: Extract Identifiers
|
|
21
|
+
// Parse JWT from headers if not already attached (Fastify might attach it to req.user)
|
|
22
|
+
const jwtTid = req.user?.tid
|
|
23
|
+
const headerTid = req.headers['x-tenant-id']
|
|
24
|
+
|
|
25
|
+
// 3. Validation Logic (Strict)
|
|
26
|
+
// Rule A: Header is MANDATORY in Multi-Tenant
|
|
27
|
+
if (!headerTid) {
|
|
28
|
+
throw new Error('Multi-Tenancy Error: Missing x-tenant-id header')
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Rule B: JWT is OPTIONAL (For Public Routes/Login)
|
|
32
|
+
// If JWT is missing, we trust the Header (Auth Guard will block Protected Routes later if Token is missing)
|
|
33
|
+
// if (!jwtTid) { ... } // REMOVED STRICT CHECK
|
|
34
|
+
|
|
35
|
+
// Rule C: Must Match (Security against Spoofing)
|
|
36
|
+
// If a user IS authenticated, they MUST allow match the requested tenant header.
|
|
37
|
+
if (jwtTid && headerTid) {
|
|
38
|
+
if (jwtTid !== headerTid) {
|
|
39
|
+
throw new Error('Security Alert: JWT Tenant ID mismatch with Header Tenant ID')
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const tenantId = headerTid || jwtTid
|
|
44
|
+
|
|
45
|
+
// 4. If no identifier found, return null (404 handled by caller)
|
|
46
|
+
if (!tenantId) {
|
|
47
|
+
if ((global as any).log?.d) (global as any).log.debug('[TenantManager] No tenant ID found in request')
|
|
48
|
+
return null
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// 5. Database Lookup
|
|
52
|
+
// We must use the specific 'Tenant' entity which extends BaseEntity
|
|
53
|
+
// Assuming the user has registered a class named 'Tenant' in entities
|
|
54
|
+
const tenantRepo = this.dataSource.getRepository(Tenant)
|
|
55
|
+
const tenant = await tenantRepo.findOne({ where: { id: tenantId } })
|
|
56
|
+
|
|
57
|
+
if (!tenant) {
|
|
58
|
+
if ((global as any).log?.w) (global as any).log.warn(`[TenantManager] Tenant ${tenantId} not found in DB`)
|
|
59
|
+
return null
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// 6. Access Control (Optional but recommended)
|
|
63
|
+
// Verify if the authenticated user (req.user) belongs to this tenant
|
|
64
|
+
// This logic might depend on the specific 'User' entity structure, so we keep it basic for the library
|
|
65
|
+
|
|
66
|
+
return tenant
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async switchContext(tenant: Tenant, db?: EntityManager) {
|
|
70
|
+
const driver = this.dataSource.driver.options.type
|
|
71
|
+
|
|
72
|
+
if (driver === 'postgres') {
|
|
73
|
+
const schema = tenant.dbSchema || 'public'
|
|
74
|
+
const safeSchema = schema.replace(/[^a-z0-9_]/gi, '')
|
|
75
|
+
|
|
76
|
+
if (db) {
|
|
77
|
+
if ((global as any).log?.t) (global as any).log.trace(`[TenantManager] Context-Aware Switch Schema to: ${safeSchema}`)
|
|
78
|
+
await db.query(`SET search_path TO "${safeSchema}", public`)
|
|
79
|
+
} else {
|
|
80
|
+
if ((global as any).log?.w) (global as any).log.warn('[TenantManager] ⚠️ Switching Global Connection Pool Context! Use generic .use(req.db) pattern instead.')
|
|
81
|
+
await this.dataSource.query(`SET search_path TO "${safeSchema}", public`)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
} else if (driver === 'mongodb') {
|
|
85
|
+
// FIXME: Mongo Multi-Tenancy isolation is incomplete
|
|
86
|
+
if ((global as any).log?.w) (global as any).log.warn('[TenantManager] Mongo Multi-Tenancy context switch is not enforcing isolation yet.')
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async createTenant(data: any): Promise<void> {
|
|
91
|
+
const driver = this.dataSource.driver.options.type
|
|
92
|
+
|
|
93
|
+
if (driver === 'postgres') {
|
|
94
|
+
const schema = data.dbSchema
|
|
95
|
+
if (!schema) throw new Error('dbSchema is required for Postgres Multi-Tenancy')
|
|
96
|
+
|
|
97
|
+
const safeSchema = schema.replace(/[^a-z0-9_]/gi, '')
|
|
98
|
+
await this.dataSource.query(`CREATE SCHEMA IF NOT EXISTS "${safeSchema}"`)
|
|
99
|
+
if ((global as any).log?.i) (global as any).log.info(`[TenantManager] Created Schema: ${safeSchema}`)
|
|
100
|
+
|
|
101
|
+
} else {
|
|
102
|
+
throw new Error(`createTenant not implemented for driver: ${driver}`)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async deleteTenant(_id: string): Promise<void> {
|
|
107
|
+
// TODO: Retrieve tenant schema by ID and implement safe drop logic
|
|
108
|
+
throw new Error('deleteTenant requires full implementation with Safety Checks (Drop Schema is dangerous)')
|
|
109
|
+
}
|
|
110
|
+
}
|