import { inject } from '@loopback/context'; import { CoreBindings, ApplicationConfig } from '@loopback/core'; import { RestApplication, RestBindings } from '@loopback/rest'; import { OpenApiSpec } from '@loopback/openapi-v3-types'; import { AuthenticationComponent, registerAuthenticationStrategy } from '@loopback/authentication'; import * as RepoClass from '@loopback/repository'; import { TokenServiceBindings, TokenServiceValues, PasswordServiceBindings, PasswordServiceValues, PermissionServiceBindings, PermissionChecker, UserServiceBindings, UserServiceValues, AppJWTTokenService, AppPasswordService, AppUserService, } from './services'; import { AuthStrategyBasic, AuthStrategyJWT, } from './strategies'; import { AuthController, UserController, UserGroupController, PermissionController, UserRepository, UserGroupRepository, UserToGroupRepository, UserGroupEndPointPermissionRepository, UserEndPointPermissionRepository, UserDataSource, } from '.'; export class AuthComponent extends AuthenticationComponent { constructor( @inject(RestBindings.API_SPEC) protected spec: OpenApiSpec, @inject(CoreBindings.APPLICATION_INSTANCE) protected app: RestApplication, @inject(CoreBindings.APPLICATION_CONFIG) protected cfg: ApplicationConfig, ) { super(); const config = cfg.lbextAuth||{}; this.patchLoopback(); this.setupBindings(); this.setupDefaultArtifacts(config.defaultArtifacts); registerAuthenticationStrategy(app, AuthStrategyJWT); registerAuthenticationStrategy(app, AuthStrategyBasic); this.updateOpenApi(spec); } setupBindings (): void { this.app.bind(TokenServiceBindings.SECRET) .to(TokenServiceValues.SECRET); this.app.bind(TokenServiceBindings.ISSUER) .to(TokenServiceValues.ISSUER); this.app.bind(TokenServiceBindings.AUDIENCE) .to(TokenServiceValues.AUDIENCE); this.app.bind(TokenServiceBindings.EXPIRES_IN).to(TokenServiceValues.EXPIRES_IN); this.app.bind(PasswordServiceBindings.SALT) .to(PasswordServiceValues.SALT); this.app.bind(PasswordServiceBindings.LENGTH) .to(PasswordServiceValues.LENGTH); this.app.bind(TokenServiceBindings.SERVICE_JWT).toClass(AppJWTTokenService); this.app.bind(PasswordServiceBindings.SERVICE).toClass(AppPasswordService); this.app.bind(PermissionServiceBindings.SERVICE).toClass(PermissionChecker); this.app.bind(UserServiceBindings.SERVICE) .toClass(AppUserService); this.app.bind(UserServiceBindings.DS_CFG) .to(UserServiceValues.DS_CFG); } setupDefaultArtifacts (artifacts: any = {}): void { if (artifacts.controllers && artifacts.controllers.auth) { this.app.bind('controllers.AuthController') .toClass(AuthController); } if (artifacts.controllers && artifacts.controllers.user) { this.app.bind('controllers.UserController') .toClass(UserController); this.app.bind('controllers.UserGroupController') .toClass(UserGroupController); this.app.bind('controllers.PermissionController') .toClass(PermissionController); } if (artifacts.repositories && artifacts.repositories.repoUser) { this.app.bind('repositories.UserRepository') .toClass(UserRepository); this.app.bind(UserServiceBindings.REPO_USER) .toClass(UserRepository); this.app.bind('repositories.UserGroupRepository') .toClass(UserGroupRepository); this.app.bind(UserServiceBindings.REPO_GROUP) .toClass(UserGroupRepository); this.app.bind('repositories.UserToGroupRepository') .toClass(UserToGroupRepository); this.app.bind(UserServiceBindings.REPO_USR2GRP) .toClass(UserToGroupRepository); this.app.bind('repositories.UserGroupEndPointPermissionRepository') .toClass(UserGroupEndPointPermissionRepository); this.app.bind(UserServiceBindings.REPO_UGEPPERM) .toClass(UserGroupEndPointPermissionRepository); this.app.bind('repositories.UserEndPointPermissionRepository') .toClass(UserEndPointPermissionRepository); this.app.bind(UserServiceBindings.REPO_UEPPERM) .toClass(UserEndPointPermissionRepository); } if (artifacts.datasources && artifacts.datasources.dataUser) { this.app.bind('datasources.UserDataSource') .toClass(UserDataSource); this.app.bind(UserServiceBindings.DS) .toClass(UserDataSource); } } updateOpenApi (spec: OpenApiSpec): void { if (!spec) return; if (!spec.components) { spec.components = {}; } if (!spec.components.securitySchemes) { spec.components.securitySchemes = {}; } let securitySchemes = spec.components.securitySchemes; securitySchemes = Object.assign(securitySchemes, { basic: { description: "HTTP authentication by basic format with user:password", type: "http", scheme: "basic", }, bearer: { description: "HTTP authentication by bearer format with token", type: 'http', scheme: 'bearer', bearerFormat: "Bearer", }, jwt: { description: "Third-party front-end application request authentication", type: 'apiKey', in: 'header', name: 'jwt', }, }); } patchLoopback () { //RepoClass.DefaultCrudRepository.createHasManyThroughRepositoryFactoryFor = //RepoClass.HasManyThroughRepositoryFactory = {}; } }