loopbackio / loopback-next

LoopBack makes it easy to build modern API applications that require complex integrations.
https://loopback.io
Other
4.95k stars 1.07k forks source link

When I am trying to login then showing the error message . #6959

Closed Arathy-sivan closed 3 years ago

Arathy-sivan commented 3 years ago
src/controllers/ctr-users.controller.ts:78:18 - error TS2345: Argument of type '{ description: string; required: boolean; content: { 'application/json': { schema: { type: string; required: string[]; properties: { login: { type: string; }; password: { type: string; minLength: number; }; }; }; }; }; }' is not assignable to parameter of type 'Partial<RequestBodyObject>'.
  Types of property 'content' are incompatible.
    Type '{ 'application/json': { schema: { type: string; required: string[]; properties: { login: { type: string; }; password: { type: string; minLength: number; }; }; }; }; }' is not assignable to type 'ContentObject'.
      Property ''application/json'' is incompatible with index signature.
        Type '{ schema: { type: string; required: string[]; properties: { login: { type: string; }; password: { type: string; minLength: number; }; }; }; }' is not assignable to type 'MediaTypeObject'.
          Types of property 'schema' are incompatible.
            Type '{ type: string; required: string[]; properties: { login: { type: string; }; password: { type: string; minLength: number; }; }; }' is not assignable to type 'ReferenceObject | SchemaObject | undefined'.
              Type '{ type: string; required: string[]; properties: { login: { type: string; }; password: { type: string; minLength: number; }; }; }' is not assignable to type 'SchemaObject'.
                Types of property 'type' are incompatible.
                  Type 'string' is not assignable to type '"string" | "number" | "boolean" | "object" | "integer" | "null" | "array" | undefined'.

78     @requestBody(CredentialsRequestBody) credentials: Credentials,

My controller is

// Uncomment these imports to begin using these cool features!

import { inject } from "@loopback/core";
import { repository } from "@loopback/repository";
import { getJsonSchemaRef, post, requestBody } from "@loopback/rest";
import { TokenServiceBindings, UserServiceBindings } from "../keys";
import { MdlUsers } from "../models";
import { Credentials, MdlUsersRepository } from "../repositories";
import { JWTService } from "../services/jwt-service";
import { MyUserService } from "../services/user-service";
import { CredentialsRequestBody } from "./specs/ctr-users-controller.specs";

// import {inject} from '@loopback/core';

export class CtrUsersController {
  constructor(
    @repository(MdlUsersRepository) public userRepository: MdlUsersRepository,
    @inject(TokenServiceBindings.TOKEN_SERVICE)
    public jwtService: JWTService,
    @inject(UserServiceBindings.USER_SERVICE)
    public userService: MyUserService,
  ) { }
  @post('users/signup', {
    responses: {
      '200': {
        description: 'NewUser',
        content: {
          'application/json':{
       // content: {
          /* schema:{
             type: 'object',
             properties: {
               password: {
                 type: 'string',
               },
             },
           },*/
          schema: getJsonSchemaRef(MdlUsers),
        },
      },
    },
  },
  })
  /* async signup(@requestBody() password:string) {
     const md5 = require('md5')
     var password = 'geeks123'
     console.log('Normal password : ', password)
     console.log('Hashed password : ', md5(password))
   }*/
  async signup(@requestBody() user: MdlUsers) {
    const md5 = require('md5')
    user.password = md5(user.password);
    const savedUser = await this.userRepository.create(user);
    //delete savedUser.password;
    return savedUser;

  }
  @post('/users/login', {
    responses: {
      '200': {
        description: 'Token',
        content: {
          'application/json': {
            schema: {
              type: 'object',
              properties: {
                token: {
                  type: 'string',
                },
              },
            },
          },
        },
      },
    },
  })
  async login(
    @requestBody(CredentialsRequestBody) credentials: Credentials,
  ): Promise<{ token: string }> {
    // ensure the user exists, and the password is correct
    const user = await this.userService.verifyCredentials(credentials);

    // convert a User object into a UserProfile object (reduced set of properties)
    const userProfile = this.userService.convertToUserProfile(user);

    // create a JSON Web Token based on the user profile
    const token = await this.jwtService.generateToken(userProfile);

    //insert generated token into the database
    const update_token = await this.userRepository.updateById(userProfile.id, { token: token })

    return { token };
  }
}

How to solve this error?

dhmlau commented 3 years ago

@Arathy-sivan, could you please provide more information on how to reproduce this problem? Are you using the todo-jwt example? Thanks.

raymondfeng commented 3 years ago

@Arathy-sivan You probably didn't see my comment in the other issue. Please see https://loopback.io/doc/en/lb4/changelog.openapi-v3.html#breaking-changes

Arathy-sivan commented 3 years ago

@Arathy-sivan You probably didn't see my comment in the other issue. Please see https://loopback.io/doc/en/lb4/changelog.openapi-v3.html#breaking-changes

Is this given to "openapi-spec.ts" file??

hacksparrow commented 3 years ago

@Arathy-sivan please share a simple app reproducing the error, I will take a look what's going on.

Arathy-sivan commented 3 years ago

@Arathy-sivan please share a simple app reproducing the error, I will take a look what's going on.

src.zip

achrinza commented 3 years ago

In the CredentialsRequestBody variable, change type: string to type: 'string' (notice it's a "string" instead of the JavaScript primitive String)

achrinza commented 3 years ago

src.zip

Just a friendly heads up, most open source company policies (mine included) disallow downloading unknown ZIP files directly due to security concerns - Please consider creating a GitHub repo that can be cloned by the developers. You can also create a separate GitHub organization just for these things so that it doesn't pollute your main GitHub account - This is what I do with https://github.com/achrinzatest and https://github.com/achrinzafork.

Arathy-sivan commented 3 years ago

In the CredentialsRequestBody variable, change type: string to type: 'string' (notice it's a "string" instead of the JavaScript primitive String)

There is no change in error when changing type

hacksparrow commented 3 years ago

@Arathy-sivan please share the project on GitHub as mentioned by @achrinza.

carlosconnected commented 3 years ago

You need to explicitly enforce the inference. Update the definition of your CredentialsRequestBody's schema and explicitly type it:

...
import {SchemaObject} from '@loopback/openapi-v3';
...

const CredentialsSchema: SchemaObject = {
  type: 'string',
  required: [],
  properties: {
    login: {
      type: 'string',
    },
    password: {
      type: 'string',
      minLength: 5,
    },
  },
};
...
const CredentialsRequestBody: SchemaObject = {
  ...
  'application/json': {schema: CredentialsSchema},
  ...
};
Arathy-sivan commented 3 years ago

You need to explicitly enforce the inference. Update the definition of your CredentialsRequestBody's schema and explicitly type it:

...
import {SchemaObject} from '@loopback/openapi-v3';
...

const CredentialsSchema: SchemaObject = {
  type: 'string',
  required: [],
  properties: {
    login: {
      type: 'string',
    },
    password: {
      type: 'string',
      minLength: 5,
    },
  },
};
...
const CredentialsRequestBody: SchemaObject = {
  ...
  'application/json': {schema: CredentialsSchema},
  ...
};

While executing this code results the error shown below:

{ "resource": "/d:/tech/hr-be/src/controllers/ctr-users.controller.ts", "owner": "typescript", "code": "2345", "severity": 8, "message": "Argument of type 'SchemaObject' is not assignable to parameter of type 'Partial'.\n Types of property 'required' are incompatible.\n Type 'string[] | undefined' is not assignable to type 'boolean | undefined'.\n Type 'string[]' is not assignable to type 'boolean | undefined'.\n Type 'string[]' is not assignable to type 'true'.", "source": "ts", "startLineNumber": 77, "startColumn": 18, "endLineNumber": 77, "endColumn": 40 }

jannyHou commented 3 years ago

@Arathy-sivan I haven't followed all the discussion but looking at

const CredentialsRequestBody: SchemaObject = {
  ...
  'application/json': {schema: CredentialsSchema},
  ...
};

The type of CredentialsRequestBody shouldn't be SchemaObject, but RequestBodyObject instead. See an example of RequestBodyObject in https://github.com/strongloop/loopback-next/blob/7f764e109a23da5e03f9a0bee93ba0c7c7d21e81/packages/rest/src/__tests__/helpers.ts#L21.