Skip to content

Commit

Permalink
register with password,login and logout API (#21) (#22)
Browse files Browse the repository at this point in the history
* register with password,login and logout API

* changed password length

Co-authored-by: vishnuvinay89 <vishnu.vinay@tekditechnologies.com>
  • Loading branch information
ManojNathIC and vishnuvinay89 authored Dec 3, 2024
1 parent 2df0e2d commit b26c951
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 10 deletions.
11 changes: 11 additions & 0 deletions src/modules/auth/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,17 @@ export class AuthController {
return res.status(registerUser.statusCode).json({ ...registerUser});
}

@Post('/register_with_password')
@UsePipes(new ValidationPipe())
@ApiBody({ type: RegisterDTO })
@ApiResponse({ status: 200, description: 'User registered successfully.' })
@ApiResponse({ status: 409, description: 'Mobile number already exists.' })
@ApiResponse({ status: 400, description: 'Bad Request.' })
public async registerWithUsernamePassword(@Body() body: RegisterDTO,@Res() res: Response) {
const registerUser=await this.authService.registerWithUsernamePassword(body)
return res.status(registerUser.statusCode).json({ ...registerUser});
}

@Post('/login')
@UsePipes(ValidationPipe)
login(@Req() req: Request, @Res() response: Response) {
Expand Down
92 changes: 91 additions & 1 deletion src/modules/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export class AuthService {
})
.catch((error) => {
console.log(JSON.stringify(error));
});;
});

// Step 6: Return success response
return new SuccessResponse({
Expand All @@ -103,6 +103,96 @@ export class AuthService {
return this.handleRegistrationError(error, body?.keycloak_id);
}
}
public async registerWithUsernamePassword(body) {
try {
// Step 2: Prepare user data for Keycloak registration
const dataToCreateUser = this.prepareUserDataV2(body);
let { password, ...rest } = dataToCreateUser;
let userName = dataToCreateUser.username;

// Step 3: Get Keycloak admin token
const token = await this.keycloakService.getAdminKeycloakToken();
this.validateToken(token);

// Step 4: Register user in Keycloak
const keycloakId = await this.registerUserInKeycloak(
rest,
token.access_token,
);

// Step 5: Register user in PostgreSQL
const userData = {
...body,
keycloak_id: keycloakId,
username: dataToCreateUser.username,
};
const user = await this.userService.createKeycloakData(userData);

const beneficiaryUrl = `${process.env.BENEFICIARY_BACKEND_URL}/users/create`
const beneficiaryData = JSON.stringify({
firstName: body.firstName,
lastName: body.lastName,
phoneNumber: body.phoneNumber || '',
sso_provider: 'keycloak',
sso_id: userData.keycloak_id
});
await axios.post(beneficiaryUrl,beneficiaryData,{
headers: {
'Content-Type': 'application/json',
Accept: '*/*',
},
}).then((response) => {
})
.catch((error) => {
console.log(JSON.stringify(error));
});


// Step 6: Return success response
return new SuccessResponse({
statusCode: HttpStatus.OK,
message: 'User created successfully',
data: { user, userName, password },
});
} catch (error) {
return this.handleRegistrationError(error, body?.keycloak_id);
}
}

private prepareUserDataV2(body) {
const trimmedFirstName = body?.firstName?.trim();
const trimmedLastName = body?.lastName?.trim();
const trimmedPhoneNumber = body?.phoneNumber?.trim();
const password =
body?.password?.trim() || process.env.SIGNUP_DEFAULT_PASSWORD;

return {
enabled: 'true',
firstName: trimmedFirstName,
lastName: trimmedLastName,
username:
trimmedFirstName +
'_' +
trimmedLastName?.charAt(0) +
'_' +
trimmedPhoneNumber?.slice(-4),
credentials: [
{
type: 'password',
value: password,
temporary: false,
},
],
password, // Return the password directly
attributes: {
// Custom user attributes
phoneNumber: '+91' + trimmedPhoneNumber,
firstName: trimmedFirstName,
lastName: trimmedLastName,
},
};
}

private async checkMobileExistence(phoneNumber: string) {
if (!phoneNumber || !/^\d{10}$/.test(phoneNumber)) {
throw new ErrorResponse({
Expand Down
21 changes: 12 additions & 9 deletions src/modules/auth/dto/register.dto.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsNotEmpty, IsString, Matches, MinLength } from 'class-validator';
import { IsNotEmpty, IsOptional, IsString, Matches, MinLength } from 'class-validator';

export class RegisterDTO {
@ApiProperty({})
Expand All @@ -20,12 +20,15 @@ export class RegisterDTO {
})
phoneNumber: string;

// @ApiProperty({})
// @IsNotEmpty({ message: 'Password is required' })
// @MinLength(8, { message: 'Password must be at least 8 characters long' })
// @Matches(/^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[\W_]).*$/, {
// message:
// 'Password must contain at least one uppercase letter, one lowercase letter, one number, and one special character',
// })
// password: string;
@ApiProperty({})
@IsOptional()
@MinLength(4, { message: 'Password must be at least 4 characters long' })
// @Matches(
// /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]+$/,
// {
// message:
// 'Password must contain uppercase, lowercase, number, and special character',
// },
// )
password: string;
}

0 comments on commit b26c951

Please sign in to comment.