Skip to content

Commit

Permalink
API to login user with an unique Id
Browse files Browse the repository at this point in the history
  • Loading branch information
Amruth-Vamshi committed Jun 7, 2024
1 parent 469c047 commit 46b8f7d
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 1 deletion.
25 changes: 24 additions & 1 deletion src/api/api.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import {
SignupResponse,
UserRegistration,
UsersResponse,
ResponseCode,
ResponseStatus
} from './api.interface';
import { ApiService } from './api.service';
import { ConfigResolverService } from './config.resolver.service';
Expand All @@ -27,10 +29,12 @@ import { RefreshRequest } from '@fusionauth/typescript-client/build/src/FusionAu
import { ChangePasswordDTO } from './dto/changePassword.dto';
import { SentryInterceptor } from '../interceptors/sentry.interceptor';
import * as Sentry from '@sentry/node';
import { LoginDto } from './dto/login.dto';
import { LoginDto, LoginWithUniqueIdDto } from './dto/login.dto';
import { SendOtpDto } from './dto/send-otp.dto';
import { VerifyOtpDto } from './dto/verify-otp.dto';
import { Throttle, SkipThrottle} from '@nestjs/throttler';
import { ConfigService } from '@nestjs/config';
import { v4 as uuidv4 } from 'uuid';
// eslint-disable-next-line @typescript-eslint/no-var-requires
const CryptoJS = require('crypto-js');

Expand All @@ -40,6 +44,7 @@ CryptoJS.lib.WordArray.words;
@UseInterceptors(SentryInterceptor)
export class ApiController {
constructor(
private configService: ConfigService,
private readonly fusionAuthService: FusionauthService,
private readonly otpService: OtpService,
private readonly apiService: ApiService,
Expand Down Expand Up @@ -358,4 +363,22 @@ export class ApiController {
): Promise<any> {
return await this.apiService.loginWithOtp(user, authHeader);
}

@Post('login-with-unique-id')
@UsePipes(new ValidationPipe({ transform: true }))
async loginWithUniqueId(
@Body() user: LoginWithUniqueIdDto,
@Headers('authorization') authHeader,
@Headers('ADMIN-API-KEY') adminApiKey
): Promise<any> {
if(adminApiKey!=this.configService.get('ADMIN_API_KEY')){
const response: SignupResponse = new SignupResponse().init(uuidv4());
response.responseCode = ResponseCode.FAILURE;
response.params.err = 'UNAUTHORIZED';
response.params.errMsg = 'Invalid admin api key';
response.params.status = ResponseStatus.failure;
return response;
}
return await this.apiService.loginWithUniqueId(user, authHeader);
}
}
51 changes: 51 additions & 0 deletions src/api/api.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const CryptoJS = require('crypto-js');
// eslint-disable-next-line @typescript-eslint/no-var-requires
const AES = require('crypto-js/aes');
import Flagsmith from 'flagsmith-nodejs';
import { LoginWithUniqueIdDto } from './dto/login.dto';

CryptoJS.lib.WordArray.words;

Expand Down Expand Up @@ -637,6 +638,56 @@ export class ApiService {
}
}

async loginWithUniqueId(loginDto: LoginWithUniqueIdDto, authHeader: null | string): Promise<SignupResponse> {
/* Execution flow
1. Check if user exists for the given applicationId and loginId.
3.1. If existing user, login user with default password.
3.2. If new user, register to this application.
4. Send login response with the token
*/
const salt = this.configResolverService.getSalt(loginDto.applicationId);
let password = salt + this.configService.get("DEFAULT_USER_PASSWORD"); // mix OTP with salt
console.log(password)

const {
statusFA
}: { statusFA: FAStatus} =
await this.fusionAuthService.getUser(
loginDto.loginId,
loginDto.applicationId,
authHeader,
);
if (statusFA === FAStatus.USER_EXISTS) {
return this.login({...loginDto,password}, authHeader);
} else {
// create a new user
const createUserPayload: UserRegistration = {
user: {
timezone: "Asia/Kolkata",
username: loginDto.loginId,
password: password
},
registration: {
applicationId: loginDto.applicationId,
preferredLanguages: [
"en"
],
roles: [],
}
}
const { userId, user, err }: { userId: UUID; user: User; err: Error } =
await this.fusionAuthService.createAndRegisterUser(
createUserPayload,
loginDto.applicationId,
authHeader,
);
if (userId == null || user == null) {
throw new HttpException(err, HttpStatus.BAD_REQUEST);
}
return this.login({...loginDto,password}, authHeader);
}
}

async updateUserRegistration(
applicationId: UUID,
authHeader: null | string,
Expand Down
12 changes: 12 additions & 0 deletions src/api/dto/login.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,15 @@ export class LoginDto {
@IsNotEmpty()
applicationId: string;
}


export class LoginWithUniqueIdDto {
@IsString()
@IsNotEmpty()
@MaxLength(80)
loginId: string;

@IsUUID()
@IsNotEmpty()
applicationId: string;
}

0 comments on commit 46b8f7d

Please sign in to comment.