import {BootMixin} from '@loopback/boot'; import {ApplicationConfig} from '@loopback/core'; import { RestExplorerBindings, RestExplorerComponent, } from '@loopback/rest-explorer'; import {RepositoryMixin} from '@loopback/repository'; import {RestApplication} from '@loopback/rest'; import {ServiceMixin} from '@loopback/service-proxy'; import path from 'path'; import dotenv from 'dotenv'; import dotenvExt from 'dotenv-extended'; import { PatientCareGiverComponent, PatientMedicineLogComponent, } from './components'; import { BearerVerifierBindings, BearerVerifierType, BearerVerifierConfig, BearerVerifierComponent, rateLimitKeyGen, } from '@sourcefuse-npm/alivio-lib'; import { AuditLogDataSource, AuthServiceDataSource, AwsS3ConfigProvider, CareGroupServiceDataSource, ChatServiceDataSource, EhrDataSource, MedicineLogDataSource, NotifServiceDataSource, PatientFacadeComponent, PatientOnboardingServiceDataSource, PatientServiceDataSource, TenantConnectorServiceDataSource, UnomiDataSource, UsersDataSource, AppointmentsComponent, } from '@sourcefuse-npm/patient-facade'; import {AuthenticationComponent} from 'loopback4-authentication'; import { AuthorizationBindings, AuthorizationComponent, } from 'loopback4-authorization'; import { Loopback4HelmetComponent, HelmetSecurityBindings, } from 'loopback4-helmet'; import { RateLimiterComponent, RateLimitSecurityBindings, } from 'loopback4-ratelimiter'; import {AWSS3Bindings, AwsS3Component} from 'loopback4-s3'; import {InfinityLibComponent} from '@local/core'; export {ApplicationConfig}; export class PatientFacadeApplication extends BootMixin( ServiceMixin(RepositoryMixin(RestApplication)), ) { constructor(options: ApplicationConfig = {}) { const port = 3000; dotenv.config(); dotenvExt.load({ schema: '.env.example', errorOnMissing: true, includeProcessEnv: true, }); options.rest = options.rest ?? {}; options.rest.basePath = process.env.BASE_PATH ?? ''; options.rest.port = +(process.env.PORT ?? port); options.rest.host = process.env.HOST; options.rest.openApiSpec = { endpointMapping: { [`${options.rest.basePath}/openapi.json`]: { version: '3.0.0', format: 'json', }, }, }; super(options); // Set up the custom sequence // Set up default home page this.static('/', path.join(__dirname, '../public')); // Customize @loopback/rest-explorer configuration here this.configure(RestExplorerBindings.COMPONENT).to({ path: '/explorer', }); this.component(RestExplorerComponent); // Add authentication component this.component(AuthenticationComponent); // Add bearer verifier component this.bind(BearerVerifierBindings.Config).to({ authServiceUrl: process.env.AUTH_SERVICE_URL, type: BearerVerifierType.facade, } as BearerVerifierConfig); this.component(BearerVerifierComponent); this.bind(AWSS3Bindings.Config).toProvider(AwsS3ConfigProvider); this.component(AwsS3Component); this.component(PatientFacadeComponent); this.component(PatientCareGiverComponent); this.component(PatientMedicineLogComponent); this.component(AppointmentsComponent); this.setUpDataSource(); this.component(InfinityLibComponent); // Add authorization component this.bind(AuthorizationBindings.CONFIG).to({ allowAlwaysPaths: ['/explorer', '/openapi.json'], }); this.component(AuthorizationComponent); this.component(Loopback4HelmetComponent); this.bind(HelmetSecurityBindings.CONFIG).to({ referrerPolicy: { policy: 'same-origin', }, contentSecurityPolicy: { directives: { frameSrc: ["'self'"], }, }, }); this.component(RateLimiterComponent); this.bind(RateLimitSecurityBindings.CONFIG).to({ name: 'RateLimitStore', max: Number(process.env.RATE_LIMIT_REQUEST_CAP), keyGenerator: rateLimitKeyGen, }); this.projectRoot = __dirname; // Customize @loopback/boot Booter Conventions here this.bootOptions = { controllers: { // Customize ControllerBooter Conventions here dirs: ['controllers'], extensions: ['.controller.js'], nested: true, }, }; } setUpDataSource() { this.dataSource(PatientOnboardingServiceDataSource); this.dataSource(PatientServiceDataSource); this.dataSource(UsersDataSource); this.dataSource(ChatServiceDataSource); this.dataSource(CareGroupServiceDataSource); this.dataSource(AuthServiceDataSource); this.dataSource(NotifServiceDataSource); this.dataSource(AuditLogDataSource); this.dataSource(EhrDataSource); this.dataSource(TenantConnectorServiceDataSource); this.dataSource(MedicineLogDataSource); this.dataSource(UnomiDataSource); } }