import { authenticate , TokenService } from '@loopback/authentication' ; import { Credentials , MyUserService , TokenServiceBindings , User , UserRepository , UserServiceBindings , } from '@loopback/authentication-jwt' ; import { inject } from '@loopback/core' ; import { model , property , repository } from '@loopback/repository' ; import { get , getModelSchemaRef , post , requestBody , SchemaObject , } from '@loopback/rest' ; import { SecurityBindings , securityId , UserProfile } from '@loopback/security' ; import { genSalt , hash } from 'bcryptjs' ; import _ from 'lodash' ; @ model ( ) export class NewUserRequest extends User { @ property ( { type : 'string' , required : true , } ) password : string ; } const CredentialsSchema = { type : 'object' , required : [ 'email' , 'password' ] , properties : { email : { type : 'string' , format : 'email' , } , password : { type : 'string' , minLength : 8 , } , } , } ; export const CredentialsRequestBody = { description : 'The input of login function' , required : true , content : { 'application/json' : { schema : CredentialsSchema } , } , } ; export class UserController { constructor ( @ inject ( TokenServiceBindings . TOKEN_SERVICE ) public jwtService , @ inject ( UserServiceBindings . USER_SERVICE ) public userService , @ inject ( SecurityBindings . USER , { optional : true } ) public user , @ repository ( UserRepository ) protected userRepository ) { } @ post ( '/users/login' , { responses : { '200' : { description : 'Token' , content : { 'application/json' : { schema : { type : 'object' , properties : { token : { type : 'string' , } , } , } , } , } , } , } , } ) async login ( @ requestBody ( CredentialsRequestBody ) credentials ) { const user = await this . userService . verifyCredentials ( credentials ) ; const userProfile = this . userService . convertToUserProfile ( user ) ; const token = await this . jwtService . generateToken ( userProfile ) ; return { token } ; } @ authenticate ( 'jwt' ) @ get ( '/whoAmI' , { responses : { '200' : { description : 'Return current user' , content : { 'application/json' : { schema : { type : 'string' , } , } , } , } , } , } ) async whoAmI ( @ inject ( SecurityBindings . USER ) currentUserProfile ) { return currentUserProfile [ securityId ] ; } @ post ( '/signup' , { responses : { '200' : { description : 'User' , content : { 'application/json' : { schema : { 'x-ts-type' : User , } , } , } , } , } , } ) async signUp ( @ requestBody ( { content : { 'application/json' : { schema : getModelSchemaRef ( NewUserRequest , { title : 'NewUser' , } ) , } , } , } ) newUserRequest ) { const password = await hash ( newUserRequest . password , await genSalt ( ) ) ; const savedUser = await this . userRepository . create ( _ . omit ( newUserRequest , 'password' ) ) ; await this . userRepository . userCredentials ( savedUser . id ) . create ( { password } ) ; return savedUser ; } }