Loopback 4 authentication error while binding custom service

流过昼夜 提交于 2020-07-23 08:25:27

问题


I have followed this link for creating custom service for authentication in loopback 4. I successfully created the service but while binding this service in application.ts I am getting the following error.

Argument of type 'typeof CustomUserService' is not assignable to parameter of type 'Constructor>'.
Construct signature return types 'CustomUserService' and 'UserService' are incompatible. The types returned by 'verifyCredentials(...)' are incompatible between these types. Type 'Promise' is not assignable to type 'Promise'. Property 'userCredentials' is missing in type 'import("d:/ionic-pr/loopback-projects/custom/src/models/user.model").User' but required in type 'import("d:/ionic-pr/loopback-projects/custom/node_modules/@loopback/authentication-jwt/dist/models/user.model").User'

GIT REPOSITORY - https://github.com/pratikjaiswal15/loopbck4uth

I have two models user and userCred with has one realtionship. The relation name is userCred.

here is the code

thank you in advance

application.ts

import {UserCredRepository, UserRepository} from './repositories';
import {CustomUserService} from './services/custom-user.service';
import {UserServiceBindings} from '@loopback/authentication-jwt';

// Bind user service inside constructor
    this.bind(UserServiceBindings.USER_SERVICE).toClass(CustomUserService),// error on this line

      // Bind user and credentials repository
      this.bind(UserServiceBindings.USER_REPOSITORY).toClass(
        UserRepository,
      ),

      this.bind(UserServiceBindings.USER_CREDENTIALS_REPOSITORY).toClass(
        UserCredRepository,
      )

custom-service.ts

import {UserService} from '@loopback/authentication';
import {repository} from '@loopback/repository';
import {HttpErrors} from '@loopback/rest';
import {securityId, UserProfile} from '@loopback/security';
import {compare} from 'bcryptjs';
// User --> MyUser
import {User} from '../models/user.model';
// UserRepository --> MyUserRepository
import {Credentials, UserRepository} from '../repositories/user.repository';


export class CustomUserService implements UserService<User, Credentials> {
  constructor(
    // UserRepository --> MyUserRepository
    @repository(UserRepository) public userRepository: UserRepository,
  ) {}

  // User --> MyUser
  async verifyCredentials(credentials: Credentials): Promise<User> {
    const invalidCredentialsError = 'Invalid email or password.';

    const foundUser = await this.userRepository.findOne({
      where: {email: credentials.email},
    });
    if (!foundUser) {
      throw new HttpErrors.Unauthorized(invalidCredentialsError);
    }

    const credentialsFound = await this.userRepository.findCredentials(
      foundUser.id,
    );
    if (!credentialsFound) {
      throw new HttpErrors.Unauthorized(invalidCredentialsError);
    }

    const passwordMatched = await compare(
      credentials.password,
      credentialsFound.password,
    );

    if (!passwordMatched) {
      throw new HttpErrors.Unauthorized(invalidCredentialsError);
    }

    return foundUser;
  }

  // User --> MyUser
  convertToUserProfile(user: User): UserProfile {

    let address = ''
    if (user.address) {
      address = user.address
    }

    return {
      [securityId]: user.id!.toString(),
      name: user.name,
      id: user.id,
      email: user.email,
      address: address

    };


  }
}

user.repositor.ts

import {Getter, inject} from '@loopback/core';
import {DefaultCrudRepository, HasOneRepositoryFactory, repository} from '@loopback/repository';
import {MygodDataSource} from '../datasources';
import {User, UserCred, UserRelations} from '../models';
import {UserCredRepository} from './user-cred.repository';

export type Credentials = {
  email: string;
  password: string;
};



export class UserRepository extends DefaultCrudRepository<
  User,
  typeof User.prototype.id,
  UserRelations
  > {

  public readonly userCred: HasOneRepositoryFactory<UserCred, typeof User.prototype.id>;

  constructor(
    @inject('datasources.mygod') dataSource: MygodDataSource, @repository.getter('UserCredRepository') protected userCredRepositoryGetter: Getter<UserCredRepository>,
  ) {
    super(User, dataSource);
    this.userCred = this.createHasOneRepositoryFactoryFor('userCred', userCredRepositoryGetter);
    this.registerInclusionResolver('userCred', this.userCred.inclusionResolver);
  }


  async findCredentials(
    userId: typeof User.prototype.id,
  ): Promise<UserCred | undefined> {
    try {
      return await this.userCred(userId).get();
    } catch (err) {
      if (err.code === 'ENTITY_NOT_FOUND') {
        return undefined;
      }
      throw err;
    }
  }
}

回答1:


have a brief explaination of the issue at your git post Follow you answer at https://github.com/strongloop/loopback-next/issues/5541



来源:https://stackoverflow.com/questions/61969175/loopback-4-authentication-error-while-binding-custom-service

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!