@sourceloop/ctrl-plane-tenant-management-service
Version:
Tenant Management microservice for SaaS control plane
228 lines (210 loc) • 5.99 kB
text/typescript
// Copyright (c) 2023 Sourcefuse Technologies
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
import {
Binding,
Component,
Constructor,
ControllerClass,
CoreBindings,
createBindingFromClass,
createServiceBinding,
inject,
ProviderMap,
ServiceOrProviderClass,
} from '@loopback/core';
import {Class, Model, Repository} from '@loopback/repository';
import {RestApplication} from '@loopback/rest';
import {
BearerVerifierBindings,
BearerVerifierComponent,
BearerVerifierConfig,
BearerVerifierType,
BooterBasePathMixin,
CoreComponent,
CoreControllerBooter,
CoreModelBooter,
SECURITY_SCHEME_SPEC,
ServiceSequence,
} from '@sourceloop/core';
import {AuthenticationComponent} from 'loopback4-authentication';
import {
AuthorizationBindings,
AuthorizationComponent,
} from 'loopback4-authorization';
import {
EventConnectorBinding,
LEAD_TOKEN_VERIFIER,
SYSTEM_USER,
TenantManagementServiceBindings,
} from './keys';
import {
Address,
Contact,
CreateLeadDTO,
Invoice,
Lead,
LeadToken,
ProvisioningDTO,
Resource,
Tenant,
TenantMgmtConfig,
TenantOnboardDTO,
VerifyLeadResponseDTO,
WebhookDTO,
WebhookSecret,
} from './models';
import {LeadTokenVerifierProvider, SystemUserProvider} from './providers';
import {
AddressRepository,
ContactRepository,
InvoiceRepository,
LeadRepository,
LeadTokenRepository,
ResourceRepository,
TenantMgmtConfigRepository,
TenantRepository,
WebhookSecretRepository,
} from './repositories/sequelize';
import {
CryptoHelperService,
EventConnector,
IdpHelperService,
InvoiceHelperService,
LeadAuthenticator,
NotificationService,
OnboardingService,
ProvisioningService,
WebhookHelperService,
} from './services';
import {ITenantManagementServiceConfig} from './types';
import {Booter} from '@loopback/boot';
import {LeadHelperService} from './services/lead-helper.service';
export class TenantManagementSequelizeServiceComponent implements Component {
booters?: Class<Booter>[];
constructor(
private readonly application: RestApplication,
private readonly tenantMgmtConfig?: ITenantManagementServiceConfig,
) {
this.providers = {};
// Mount core component
this.application.component(CoreComponent);
this.application.api({
openapi: '3.0.0',
info: {
title: 'Tenant Management Service',
version: '1.0.0',
},
paths: {},
components: {
securitySchemes: SECURITY_SCHEME_SPEC,
},
servers: [{url: '/'}],
});
if (!this.tenantMgmtConfig?.useCustomSequence) {
// Mount default sequence if needed
this.setupSequence();
}
this.repositories = [
AddressRepository,
ContactRepository,
InvoiceRepository,
LeadRepository,
LeadTokenRepository,
ResourceRepository,
TenantRepository,
WebhookSecretRepository,
TenantMgmtConfigRepository,
];
this.models = [
Address,
Contact,
Invoice,
Lead,
LeadToken,
Resource,
Tenant,
WebhookSecret,
CreateLeadDTO,
ProvisioningDTO,
TenantOnboardDTO,
VerifyLeadResponseDTO,
WebhookDTO,
TenantMgmtConfig,
];
this.booters = [
BooterBasePathMixin(CoreModelBooter, __dirname, {
interface: TenantManagementSequelizeServiceComponent.name,
}),
BooterBasePathMixin(CoreControllerBooter, __dirname, {
dirs: ['controllers'],
extensions: ['.controller.js'],
nested: true,
interface: TenantManagementSequelizeServiceComponent.name,
}),
];
this.bindings = [
Binding.bind(LEAD_TOKEN_VERIFIER).toProvider(LeadTokenVerifierProvider),
Binding.bind(SYSTEM_USER).toProvider(SystemUserProvider),
createServiceBinding(ProvisioningService),
createServiceBinding(OnboardingService),
createServiceBinding(LeadAuthenticator),
createServiceBinding(CryptoHelperService),
Binding.bind('services.NotificationService').toClass(NotificationService),
createServiceBinding(WebhookHelperService),
createServiceBinding(InvoiceHelperService),
createServiceBinding(IdpHelperService),
createServiceBinding(LeadHelperService),
];
this.addClassBindingIfNotPresent(EventConnectorBinding.key, EventConnector);
}
providers?: ProviderMap = {};
bindings: Binding[] = [];
services?: ServiceOrProviderClass[];
/**
* An optional list of Repository classes to bind for dependency injection
* via `app.repository()` API.
*/
repositories?: Class<Repository<Model>>[];
/**
* An optional list of Model classes to bind for dependency injection
* via `app.model()` API.
*/
models?: Class<Model>[];
/**
* An array of controller classes
*/
controllers?: ControllerClass[];
/**
* Setup ServiceSequence by default if no other sequnce provided
*
*/
setupSequence() {
this.application.sequence(ServiceSequence);
// Mount authentication component for default sequence
this.application.component(AuthenticationComponent);
// Mount bearer verifier component
this.application.bind(BearerVerifierBindings.Config).to({
authServiceUrl: '',
type: BearerVerifierType.service,
} as BearerVerifierConfig);
this.application.component(BearerVerifierComponent);
// Mount authorization component for default sequence
this.application.bind(AuthorizationBindings.CONFIG).to({
allowAlwaysPaths: ['/explorer'],
});
this.application.component(AuthorizationComponent);
}
private addClassBindingIfNotPresent<T>(key: string, cls: Constructor<T>) {
if (!this.application.isBound(key)) {
this.bindings.push(
createBindingFromClass(cls, {
key: key,
}),
);
}
}
}