Skip to content

Commit 1e4d149

Browse files
FEAT: save tenantId in execution context
1 parent 66d5966 commit 1e4d149

File tree

11 files changed

+62
-130
lines changed

11 files changed

+62
-130
lines changed

package-lock.json

Lines changed: 21 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
"twilio": "^3.67.1",
6666
"typeorm": "^0.3.11",
6767
"typeorm-naming-strategies": "^2.0.0",
68+
"uuid": "^8.3.2",
6869
"winston": "^3.3.3"
6970
},
7071
"devDependencies": {
@@ -86,6 +87,7 @@
8687
"@types/speakeasy": "^2.0.6",
8788
"@types/supertest": "^2.0.10",
8889
"@types/totp-generator": "0.0.2",
90+
"@types/uuid": "^10.0.0",
8991
"@typescript-eslint/eslint-plugin": "^4.19.0",
9092
"@typescript-eslint/parser": "^4.19.0",
9193
"eslint": "^7.22.0",

src/app.module.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Module } from '@nestjs/common';
1+
import { MiddlewareConsumer, Module } from '@nestjs/common';
22
import * as Joi from '@hapi/joi';
33
import { ConfigModule } from '@nestjs/config';
44

@@ -7,6 +7,7 @@ import { AppGraphQLModule } from './graphql/graphql.module';
77
import { UserAuthModule } from './authentication/authentication.module';
88
import { AuthorizationModule } from './authorization/authorization.module';
99
import { HealthModule } from './health/health.module';
10+
import { ExecutionContextBinder } from './middleware/executionId.middleware';
1011

1112
@Module({
1213
imports: [
@@ -30,4 +31,8 @@ import { HealthModule } from './health/health.module';
3031
controllers: [],
3132
providers: [],
3233
})
33-
export class AppModule {}
34+
export class AppModule {
35+
configure(consumer: MiddlewareConsumer) {
36+
consumer.apply(ExecutionContextBinder).forRoutes('*');
37+
}
38+
}

src/authentication/authentication.helper.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,9 @@ export class AuthenticationHelper {
1313
this.configService.get('JWT_TOKEN_EXPTIME') * 1 || 60 * 60;
1414
const secret = this.configService.get('JWT_SECRET') as string;
1515
const username = userDetails.email || userDetails.phone;
16-
const tenantId = userDetails.tenantId;
1716
const dataStoredInToken = {
1817
username: username,
19-
tenantId,
18+
tenantId: userDetails.tenantId,
2019
sub: userDetails.id,
2120
env: this.configService.get('ENV') || 'local',
2221
};

src/authentication/service/password.auth.service.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
} from '../exception/userauth.exception';
2626
import { Authenticatable } from '../interfaces/authenticatable';
2727
import { TokenService } from './token.service';
28+
import { ExecutionManager } from '../../util/execution.manager';
2829

2930
@Injectable()
3031
export default class PasswordAuthService implements Authenticatable {
@@ -68,6 +69,7 @@ export default class PasswordAuthService implements Authenticatable {
6869
async inviteTokenSignup(
6970
userDetails: UserInviteTokenSignupInput,
7071
): Promise<InviteTokenResponse> {
72+
const tenantId = ExecutionManager.getTenantId();
7173
const verifyUser = await this.userService.verifyDuplicateUser(
7274
userDetails.email,
7375
userDetails.phone,
@@ -85,6 +87,7 @@ export default class PasswordAuthService implements Authenticatable {
8587
userFromInput.middleName = userDetails.middleName;
8688
userFromInput.lastName = userDetails.lastName;
8789
userFromInput.status = Status.INVITED;
90+
userFromInput.tenantId = tenantId;
8891
let invitationToken: { token: any; tokenExpiryTime?: any };
8992
const transaction = await this.dataSource.manager.transaction(async () => {
9093
const savedUser = await this.userService.createUser(userFromInput);
@@ -104,6 +107,7 @@ export default class PasswordAuthService implements Authenticatable {
104107
lastName: user.lastName,
105108
inviteToken: user?.inviteToken,
106109
status: user.status,
110+
tenantId: user.tenantId,
107111
};
108112
return {
109113
inviteToken: invitationToken.token,

src/authorization/entity/abstract.tenant.entity.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { PrimaryColumn } from 'typeorm';
1+
import { Column } from 'typeorm';
22
import BaseEntity from './base.entity';
33

44
class AbstractTenantEntity extends BaseEntity {
5-
@PrimaryColumn({ type: 'uuid' })
5+
@Column({ type: 'uuid' })
66
public tenantId!: string;
77
}
88

src/authorization/resolver/entity.resolver.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export class EntityResolver {
5252
async updateEntityPermissions(
5353
@Args('id', ParseUUIDPipe) id: string,
5454
@Args('input') entityInput: UpdateEntityPermissionInput,
55-
): Promise<Entity[]> {
55+
): Promise<Permission[]> {
5656
return this.entityService.updateEntityPermissions(id, entityInput);
5757
}
5858

src/main.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { ValidationPipe } from '@nestjs/common';
44
import { CustomExceptionsFilter } from './exception/exception.filter';
55
import { ConfigService } from '@nestjs/config';
66
import { LoggerService } from './logger/logger.service';
7+
import { ExecutionManager } from './util/execution.manager';
78

89
async function bootstrap() {
910
const appOptions = { cors: true };
@@ -15,6 +16,8 @@ async function bootstrap() {
1516
app.useGlobalPipes(new ValidationPipe());
1617
app.useGlobalFilters(new CustomExceptionsFilter());
1718

19+
ExecutionManager.init();
20+
1821
await app.listen(configService.get('PORT') || 4000);
1922

2023
logger.info(`Application is running on: ${await app.getUrl()}`);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { NestMiddleware } from '@nestjs/common';
2+
import { NextFunction, Request, Response } from 'express';
3+
4+
import { ExecutionManager } from '../util/execution.manager';
5+
6+
export class ExecutionContextBinder implements NestMiddleware {
7+
async use(req: Request, res: Response, next: NextFunction) {
8+
ExecutionManager.runWithContext(next);
9+
}
10+
}

src/migrations/1733833844028-MultiTenantFeature.ts

Lines changed: 0 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -17,200 +17,80 @@ export class MultiTenantFeature1733833844028 implements MigrationInterface {
1717
await queryRunner.query(
1818
`ALTER TABLE "entity_model" ALTER COLUMN "tenant_id" DROP DEFAULT`,
1919
);
20-
await queryRunner.query(
21-
`ALTER TABLE "entity_model" DROP CONSTRAINT "PK_ea7e5d0ca6a0d6221f78cea499a"`,
22-
);
23-
await queryRunner.query(
24-
`ALTER TABLE "entity_model" ADD CONSTRAINT "PK_8136db3bf8c7a328973a0feb096" PRIMARY KEY ("id", "tenant_id")`,
25-
);
2620
await queryRunner.query(
2721
`ALTER TABLE "entity_permission" ADD "tenant_id" uuid NOT NULL DEFAULT '${tenantId}'`,
2822
);
2923
await queryRunner.query(
3024
`ALTER TABLE "entity_permission" ALTER COLUMN "tenant_id" DROP DEFAULT`,
3125
);
32-
await queryRunner.query(
33-
`ALTER TABLE "entity_permission" DROP CONSTRAINT "PK_22d409e099ab8a6bc3fc7b7b8a1"`,
34-
);
35-
await queryRunner.query(
36-
`ALTER TABLE "entity_permission" ADD CONSTRAINT "PK_456866ab8087e8d3a3d616dbe0a" PRIMARY KEY ("permission_id", "entity_id", "tenant_id")`,
37-
);
3826
await queryRunner.query(
3927
`ALTER TABLE "group" ADD "tenant_id" uuid NOT NULL DEFAULT '${tenantId}'`,
4028
);
4129
await queryRunner.query(
4230
`ALTER TABLE "group" ALTER COLUMN "tenant_id" DROP DEFAULT`,
4331
);
44-
await queryRunner.query(
45-
`ALTER TABLE "group" DROP CONSTRAINT "PK_256aa0fda9b1de1a73ee0b7106b"`,
46-
);
47-
await queryRunner.query(
48-
`ALTER TABLE "group" ADD CONSTRAINT "PK_3ba4cfb3cab75ac2ea4b0a9536b" PRIMARY KEY ("id", "tenant_id")`,
49-
);
5032
await queryRunner.query(
5133
`ALTER TABLE "group_permission" ADD "tenant_id" uuid NOT NULL DEFAULT '${tenantId}'`,
5234
);
5335
await queryRunner.query(
5436
`ALTER TABLE "group_permission" ALTER COLUMN "tenant_id" DROP DEFAULT`,
5537
);
56-
await queryRunner.query(
57-
`ALTER TABLE "group_permission" DROP CONSTRAINT "PK_5aadf555f3ea93c95bc952f1547"`,
58-
);
59-
await queryRunner.query(
60-
`ALTER TABLE "group_permission" ADD CONSTRAINT "PK_97edbfb9e685755fa455480f98c" PRIMARY KEY ("permission_id", "group_id", "tenant_id")`,
61-
);
6238
await queryRunner.query(
6339
`ALTER TABLE "group_role" ADD "tenant_id" uuid NOT NULL DEFAULT '${tenantId}'`,
6440
);
6541
await queryRunner.query(
6642
`ALTER TABLE "group_role" ALTER COLUMN "tenant_id" DROP DEFAULT`,
6743
);
68-
await queryRunner.query(
69-
`ALTER TABLE "group_role" DROP CONSTRAINT "PK_34b9a049ae09a85e87e7f18787b"`,
70-
);
71-
await queryRunner.query(
72-
`ALTER TABLE "group_role" ADD CONSTRAINT "PK_3a8315bbdf7bfd962bf0e7a40e5" PRIMARY KEY ("role_id", "group_id", "tenant_id")`,
73-
);
7444
await queryRunner.query(
7545
`ALTER TABLE "role" ADD "tenant_id" uuid NOT NULL DEFAULT '${tenantId}'`,
7646
);
7747
await queryRunner.query(
7848
`ALTER TABLE "role" ALTER COLUMN "tenant_id" DROP DEFAULT`,
7949
);
80-
await queryRunner.query(
81-
`ALTER TABLE "role" DROP CONSTRAINT "PK_b36bcfe02fc8de3c57a8b2391c2"`,
82-
);
83-
await queryRunner.query(
84-
`ALTER TABLE "role" ADD CONSTRAINT "PK_2b394366739f89a92b09a90aea4" PRIMARY KEY ("id", "tenant_id")`,
85-
);
8650
await queryRunner.query(
8751
`ALTER TABLE "role_permission" ADD "tenant_id" uuid NOT NULL DEFAULT '${tenantId}'`,
8852
);
8953
await queryRunner.query(
9054
`ALTER TABLE "role_permission" ALTER COLUMN "tenant_id" DROP DEFAULT`,
9155
);
92-
await queryRunner.query(
93-
`ALTER TABLE "role_permission" DROP CONSTRAINT "PK_19a94c31d4960ded0dcd0397759"`,
94-
);
95-
await queryRunner.query(
96-
`ALTER TABLE "role_permission" ADD CONSTRAINT "PK_96cb2e2da566ba65ae7f24cece2" PRIMARY KEY ("permission_id", "role_id", "tenant_id")`,
97-
);
9856
await queryRunner.query(
9957
`ALTER TABLE "user" ADD "tenant_id" uuid NOT NULL DEFAULT '${tenantId}'`,
10058
);
10159
await queryRunner.query(
10260
`ALTER TABLE "user" ALTER COLUMN "tenant_id" DROP DEFAULT`,
10361
);
104-
await queryRunner.query(
105-
`ALTER TABLE "user" DROP CONSTRAINT "PK_cace4a159ff9f2512dd42373760"`,
106-
);
107-
await queryRunner.query(
108-
`ALTER TABLE "user" ADD CONSTRAINT "PK_9a56c21022d9a4dc056d9c37575" PRIMARY KEY ("id", "tenant_id")`,
109-
);
11062
await queryRunner.query(
11163
`ALTER TABLE "user_group" ADD "tenant_id" uuid NOT NULL DEFAULT '${tenantId}'`,
11264
);
11365
await queryRunner.query(
11466
`ALTER TABLE "user_group" ALTER COLUMN "tenant_id" DROP DEFAULT`,
11567
);
116-
await queryRunner.query(
117-
`ALTER TABLE "user_group" DROP CONSTRAINT "PK_bd332ba499e012f8d20905f8061"`,
118-
);
119-
await queryRunner.query(
120-
`ALTER TABLE "user_group" ADD CONSTRAINT "PK_fe9b93596a9c69d45a04226cc40" PRIMARY KEY ("group_id", "user_id", "tenant_id")`,
121-
);
12268
await queryRunner.query(
12369
`ALTER TABLE "user_permission" ADD "tenant_id" uuid NOT NULL DEFAULT '${tenantId}'`,
12470
);
12571
await queryRunner.query(
12672
`ALTER TABLE "user_permission" ALTER COLUMN "tenant_id" DROP DEFAULT`,
12773
);
128-
await queryRunner.query(
129-
`ALTER TABLE "user_permission" DROP CONSTRAINT "PK_e55fe6295b438912cb42bce1baa"`,
130-
);
131-
await queryRunner.query(
132-
`ALTER TABLE "user_permission" ADD CONSTRAINT "PK_f63ef18a89058a5d95c171b7823" PRIMARY KEY ("permission_id", "user_id", "tenant_id")`,
133-
);
13474
}
13575

13676
public async down(queryRunner: QueryRunner): Promise<void> {
137-
await queryRunner.query(
138-
`ALTER TABLE "user_permission" DROP CONSTRAINT "PK_f63ef18a89058a5d95c171b7823"`,
139-
);
140-
await queryRunner.query(
141-
`ALTER TABLE "user_permission" ADD CONSTRAINT "PK_e55fe6295b438912cb42bce1baa" PRIMARY KEY ("permission_id", "user_id")`,
142-
);
14377
await queryRunner.query(
14478
`ALTER TABLE "user_permission" DROP COLUMN "tenant_id"`,
14579
);
146-
await queryRunner.query(
147-
`ALTER TABLE "user_group" DROP CONSTRAINT "PK_fe9b93596a9c69d45a04226cc40"`,
148-
);
149-
await queryRunner.query(
150-
`ALTER TABLE "user_group" ADD CONSTRAINT "PK_bd332ba499e012f8d20905f8061" PRIMARY KEY ("group_id", "user_id")`,
151-
);
15280
await queryRunner.query(`ALTER TABLE "user_group" DROP COLUMN "tenant_id"`);
153-
await queryRunner.query(
154-
`ALTER TABLE "user" DROP CONSTRAINT "PK_9a56c21022d9a4dc056d9c37575"`,
155-
);
156-
await queryRunner.query(
157-
`ALTER TABLE "user" ADD CONSTRAINT "PK_cace4a159ff9f2512dd42373760" PRIMARY KEY ("id")`,
158-
);
15981
await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "tenant_id"`);
160-
await queryRunner.query(
161-
`ALTER TABLE "role_permission" DROP CONSTRAINT "PK_96cb2e2da566ba65ae7f24cece2"`,
162-
);
163-
await queryRunner.query(
164-
`ALTER TABLE "role_permission" ADD CONSTRAINT "PK_19a94c31d4960ded0dcd0397759" PRIMARY KEY ("permission_id", "role_id")`,
165-
);
16682
await queryRunner.query(
16783
`ALTER TABLE "role_permission" DROP COLUMN "tenant_id"`,
16884
);
169-
await queryRunner.query(
170-
`ALTER TABLE "role" DROP CONSTRAINT "PK_2b394366739f89a92b09a90aea4"`,
171-
);
172-
await queryRunner.query(
173-
`ALTER TABLE "role" ADD CONSTRAINT "PK_b36bcfe02fc8de3c57a8b2391c2" PRIMARY KEY ("id")`,
174-
);
17585
await queryRunner.query(`ALTER TABLE "role" DROP COLUMN "tenant_id"`);
176-
await queryRunner.query(
177-
`ALTER TABLE "group_role" DROP CONSTRAINT "PK_3a8315bbdf7bfd962bf0e7a40e5"`,
178-
);
179-
await queryRunner.query(
180-
`ALTER TABLE "group_role" ADD CONSTRAINT "PK_34b9a049ae09a85e87e7f18787b" PRIMARY KEY ("role_id", "group_id")`,
181-
);
18286
await queryRunner.query(`ALTER TABLE "group_role" DROP COLUMN "tenant_id"`);
183-
await queryRunner.query(
184-
`ALTER TABLE "group_permission" DROP CONSTRAINT "PK_97edbfb9e685755fa455480f98c"`,
185-
);
186-
await queryRunner.query(
187-
`ALTER TABLE "group_permission" ADD CONSTRAINT "PK_5aadf555f3ea93c95bc952f1547" PRIMARY KEY ("permission_id", "group_id")`,
188-
);
18987
await queryRunner.query(
19088
`ALTER TABLE "group_permission" DROP COLUMN "tenant_id"`,
19189
);
192-
await queryRunner.query(
193-
`ALTER TABLE "group" DROP CONSTRAINT "PK_3ba4cfb3cab75ac2ea4b0a9536b"`,
194-
);
195-
await queryRunner.query(
196-
`ALTER TABLE "group" ADD CONSTRAINT "PK_256aa0fda9b1de1a73ee0b7106b" PRIMARY KEY ("id")`,
197-
);
19890
await queryRunner.query(`ALTER TABLE "group" DROP COLUMN "tenant_id"`);
199-
await queryRunner.query(
200-
`ALTER TABLE "entity_permission" DROP CONSTRAINT "PK_456866ab8087e8d3a3d616dbe0a"`,
201-
);
202-
await queryRunner.query(
203-
`ALTER TABLE "entity_permission" ADD CONSTRAINT "PK_22d409e099ab8a6bc3fc7b7b8a1" PRIMARY KEY ("permission_id", "entity_id")`,
204-
);
20591
await queryRunner.query(
20692
`ALTER TABLE "entity_permission" DROP COLUMN "tenant_id"`,
20793
);
208-
await queryRunner.query(
209-
`ALTER TABLE "entity_model" DROP CONSTRAINT "PK_8136db3bf8c7a328973a0feb096"`,
210-
);
211-
await queryRunner.query(
212-
`ALTER TABLE "entity_model" ADD CONSTRAINT "PK_ea7e5d0ca6a0d6221f78cea499a" PRIMARY KEY ("id")`,
213-
);
21494
await queryRunner.query(
21595
`ALTER TABLE "entity_model" DROP COLUMN "tenant_id"`,
21696
);

0 commit comments

Comments
 (0)