Skip to content

Commit

Permalink
0.27.0 (#860)
Browse files Browse the repository at this point in the history
  • Loading branch information
chavda-bhavik authored Oct 24, 2024
2 parents 89afa30 + 618ae64 commit f1f9958
Show file tree
Hide file tree
Showing 183 changed files with 5,040 additions and 720 deletions.
2 changes: 1 addition & 1 deletion apps/api/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@impler/api",
"version": "0.26.1",
"version": "0.27.0",
"author": "implerhq",
"license": "MIT",
"private": true,
Expand Down
2 changes: 2 additions & 0 deletions apps/api/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { EnvironmentModule } from './app/environment/environment.module';
import { ActivityModule } from './app/activity/activity.module';
import { UserModule } from './app/user/user.module';
import { ImportJobsModule } from 'app/import-jobs/import-jobs.module';
import { TeamModule } from 'app/team/team.module';

const modules: Array<Type | DynamicModule | Promise<DynamicModule> | ForwardReference> = [
ProjectModule,
Expand All @@ -31,6 +32,7 @@ const modules: Array<Type | DynamicModule | Promise<DynamicModule> | ForwardRefe
EnvironmentModule,
ActivityModule,
ImportJobsModule,
TeamModule,
];

const providers = [Logger];
Expand Down
36 changes: 19 additions & 17 deletions apps/api/src/app/auth/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
UseInterceptors,
} from '@nestjs/common';

import { IJwtPayload } from '@impler/shared';
import { constructQueryString, IJwtPayload, UserRolesEnum } from '@impler/shared';
import { AuthService } from './services/auth.service';
import { IStrategyResponse } from '@shared/types/auth.types';
import { CONSTANTS, COOKIE_CONFIG } from '@shared/constants';
Expand All @@ -37,8 +37,6 @@ import {
OnboardUser,
RegisterUser,
ResetPassword,
LoginUserCommand,
RegisterUserCommand,
ResetPasswordCommand,
RequestForgotPassword,
RequestForgotPasswordCommand,
Expand Down Expand Up @@ -76,7 +74,10 @@ export class AuthController {

@Get('/github/callback')
@UseGuards(AuthGuard('github'))
async githubCallback(@StrategyUser() strategyUser: IStrategyResponse, @Res() response: Response) {
async githubCallback(
@Res({ passthrough: true }) response: Response,
@StrategyUser() strategyUser: IStrategyResponse
) {
if (!strategyUser || !strategyUser.token) {
return response.redirect(`${process.env.WEB_BASE_URL}/auth/signin?error=AuthenticationError`);
}
Expand All @@ -88,11 +89,7 @@ export class AuthController {
if (strategyUser.showAddProject) {
queryObj.showAddProject = true;
}
for (const key in queryObj) {
if (queryObj.hasOwnProperty(key)) {
url += `${url.includes('?') ? '&' : '?'}${key}=${queryObj[key]}`;
}
}
url += constructQueryString(queryObj);

response.cookie(CONSTANTS.AUTH_COOKIE_NAME, strategyUser.token, {
...COOKIE_CONFIG,
Expand Down Expand Up @@ -133,7 +130,7 @@ export class AuthController {

@Post('/register')
async register(@Body() body: RegisterUserDto, @Res() response: Response) {
const registeredUser = await this.registerUser.execute(RegisterUserCommand.create(body));
const registeredUser = await this.registerUser.execute(body);

response.cookie(CONSTANTS.AUTH_COOKIE_NAME, registeredUser.token, {
...COOKIE_CONFIG,
Expand Down Expand Up @@ -170,15 +167,21 @@ export class AuthController {
},
user.email
);

const userApiKey = projectWithEnvironment.environment.apiKeys.find(
(apiKey) => apiKey._userId.toString() === user._id
);

const token = this.authService.getSignedToken(
{
_id: user._id,
firstName: user.firstName,
lastName: user.lastName,
email: user.email,
role: userApiKey.role as UserRolesEnum,
profilePicture: user.profilePicture,
isEmailVerified: user.isEmailVerified,
accessToken: projectWithEnvironment.environment.apiKeys[0].key,
accessToken: projectWithEnvironment.environment.key,
},
projectWithEnvironment.project._id
);
Expand All @@ -192,12 +195,11 @@ export class AuthController {

@Post('/login')
async login(@Body() body: LoginUserDto, @Res() response: Response) {
const loginUser = await this.loginUser.execute(
LoginUserCommand.create({
email: body.email,
password: body.password,
})
);
const loginUser = await this.loginUser.execute({
email: body.email,
password: body.password,
invitationId: body.invitationId,
});

response.cookie(CONSTANTS.AUTH_COOKIE_NAME, loginUser.token, {
...COOKIE_CONFIG,
Expand Down
9 changes: 8 additions & 1 deletion apps/api/src/app/auth/dtos/login-user.dto.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsDefined, IsString, IsEmail } from 'class-validator';
import { IsDefined, IsString, IsEmail, IsOptional } from 'class-validator';

export class LoginUserDto {
@ApiProperty({
Expand All @@ -15,4 +15,11 @@ export class LoginUserDto {
@IsString()
@IsDefined()
password: string;

@ApiProperty({
description: 'InvitationId to accept invitation later on',
})
@IsString()
@IsOptional()
invitationId?: string;
}
9 changes: 8 additions & 1 deletion apps/api/src/app/auth/dtos/register-user.dto.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsDefined, IsString, IsEmail } from 'class-validator';
import { IsDefined, IsString, IsEmail, IsOptional } from 'class-validator';

export class RegisterUserDto {
@ApiProperty({
Expand Down Expand Up @@ -29,4 +29,11 @@ export class RegisterUserDto {
@IsString()
@IsDefined()
password: string;

@ApiProperty({
description: 'InvitationId to accept invitation later on',
})
@IsString()
@IsOptional()
invitationId?: string;
}
27 changes: 9 additions & 18 deletions apps/api/src/app/auth/services/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as bcrypt from 'bcryptjs';
import { JwtService } from '@nestjs/jwt';
import { Injectable, UnauthorizedException } from '@nestjs/common';

import { IJwtPayload } from '@impler/shared';
import { IJwtPayload, UserRolesEnum } from '@impler/shared';
import { CONSTANTS, LEAD_SIGNUP_USING } from '@shared/constants';
import { UserEntity, UserRepository, EnvironmentRepository } from '@impler/dal';
import { UserNotFoundException } from '@shared/exceptions/user-not-found.exception';
Expand Down Expand Up @@ -31,6 +31,7 @@ export class AuthService {
lastName: profile.lastName,
signupMethod: LEAD_SIGNUP_USING.GITHUB,
profilePicture: profile.avatar_url,
role: UserRolesEnum.ADMIN,
...(provider ? { tokens: [provider] } : {}),
};
user = await this.userRepository.create(userObj);
Expand All @@ -54,6 +55,7 @@ export class AuthService {
email: user.email,
firstName: user.firstName,
lastName: user.lastName,
role: apiKey?.role as UserRolesEnum,
profilePicture: user.profilePicture,
accessToken: apiKey?.apiKey,
isEmailVerified: user.isEmailVerified,
Expand Down Expand Up @@ -89,6 +91,7 @@ export class AuthService {
email: user.email,
firstName: user.firstName,
lastName: user.lastName,
role: apiKey.role as UserRolesEnum,
accessToken: apiKey?.apiKey,
isEmailVerified: user.isEmailVerified,
},
Expand All @@ -109,6 +112,7 @@ export class AuthService {
email: user.email,
firstName: user.firstName,
lastName: user.lastName,
role: apiKey.role as UserRolesEnum,
accessToken: apiKey?.apiKey,
isEmailVerified: user.isEmailVerified,
},
Expand All @@ -122,6 +126,7 @@ export class AuthService {
firstName: string;
lastName: string;
email: string;
role?: UserRolesEnum;
isEmailVerified: boolean;
profilePicture?: string;
accessToken?: string;
Expand All @@ -134,6 +139,7 @@ export class AuthService {
{
_id: user._id,
_projectId,
role: user.role,
firstName: user.firstName,
lastName: user.lastName,
email: user.email,
Expand Down Expand Up @@ -173,23 +179,7 @@ export class AuthService {
const environment = await this.environmentRepository.findByApiKey(apiKey);
if (!environment) throw new UnauthorizedException('API Key not found!');

const key = environment.apiKeys.find((i) => i.key === apiKey);
if (!key) throw new UnauthorizedException('API Key not found!');

const user = await this.getUser({ _id: key._userId });
if (!user) throw new UnauthorizedException('User not found!');

return this.getSignedToken(
{
_id: user._id,
email: user.email,
firstName: user.firstName,
lastName: user.lastName,
accessToken: apiKey,
isEmailVerified: user.isEmailVerified,
},
environment._projectId
);
if (apiKey !== environment.key) throw new UnauthorizedException('API Key not found!');
}

async generateUserToken(user: UserEntity) {
Expand All @@ -201,6 +191,7 @@ export class AuthService {
email: user.email,
firstName: user.firstName,
lastName: user.lastName,
role: apiKey.role as UserRolesEnum,
accessToken: apiKey?.apiKey,
isEmailVerified: user.isEmailVerified,
},
Expand Down
10 changes: 1 addition & 9 deletions apps/api/src/app/auth/usecases/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ import { RequestForgotPassword } from './request-forgot-password/request-forgot-

import { Verify } from './verify/verify.usecase';
import { ResendOTP } from './resend-otp/resend-otp.usecase';
import { LoginUserCommand } from './login-user/login-user.command';
import { OnboardUserCommand } from './onboard-user/onboard-user.command';
import { RegisterUserCommand } from './register-user/register-user.command';
import { ResetPasswordCommand } from './reset-password/reset-password.command';
import { RequestForgotPasswordCommand } from './request-forgot-password/request-forgot-pasword.command';

Expand Down Expand Up @@ -38,11 +36,5 @@ export const USE_CASES = [
//
];

export { OnboardUserCommand, ResetPasswordCommand, RequestForgotPasswordCommand };
export { Verify, RegisterUser, LoginUser, RequestForgotPassword, ResetPassword, OnboardUser, ResendOTP, UpdateUser };
export {
LoginUserCommand,
OnboardUserCommand,
RegisterUserCommand,
ResetPasswordCommand,
RequestForgotPasswordCommand,
};
11 changes: 2 additions & 9 deletions apps/api/src/app/auth/usecases/login-user/login-user.command.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
import { IsDefined, IsEmail, IsString } from 'class-validator';
import { BaseCommand } from '@shared/commands/base.command';

export class LoginUserCommand extends BaseCommand {
@IsEmail()
@IsDefined()
export class LoginUserCommand {
email: string;

@IsString()
@IsDefined()
password: string;
invitationId?: string;
}
10 changes: 8 additions & 2 deletions apps/api/src/app/auth/usecases/login-user/login-user.usecase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { EmailService } from '@impler/services';
import { LoginUserCommand } from './login-user.command';
import { AuthService } from '../../services/auth.service';
import { EnvironmentRepository, UserRepository } from '@impler/dal';
import { EMAIL_SUBJECT, SCREENS } from '@impler/shared';
import { EMAIL_SUBJECT, SCREENS, UserRolesEnum } from '@impler/shared';
import { generateVerificationCode } from '@shared/helpers/common.helper';

@Injectable()
Expand Down Expand Up @@ -59,14 +59,20 @@ export class LoginUser {

const apiKey = await this.environmentRepository.getApiKeyForUserId(user._id);

let screen = SCREENS.ONBOARD;
if (command.invitationId) screen = SCREENS.INVIATAION;
else if (!user.isEmailVerified) screen = SCREENS.VERIFY;
else if (apiKey) screen = SCREENS.HOME;

return {
screen: !user.isEmailVerified ? SCREENS.VERIFY : apiKey ? SCREENS.HOME : SCREENS.ONBOARD,
screen,
token: this.authService.getSignedToken(
{
_id: user._id,
email: user.email,
firstName: user.firstName,
lastName: user.lastName,
role: apiKey?.role as UserRolesEnum,
profilePicture: user.profilePicture,
accessToken: apiKey?.apiKey,
isEmailVerified: user.isEmailVerified,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,7 @@
import { IsDefined, IsEmail, IsString } from 'class-validator';
import { BaseCommand } from '@shared/commands/base.command';

export class RegisterUserCommand extends BaseCommand {
@IsString()
@IsDefined()
export class RegisterUserCommand {
firstName: string;

@IsString()
@IsDefined()
lastName: string;

@IsEmail()
@IsDefined()
email: string;

@IsString()
@IsDefined()
password: string;
invitationId?: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { UserRepository } from '@impler/dal';

import { EmailService } from '@impler/services';
import { LEAD_SIGNUP_USING } from '@shared/constants';
import { SCREENS, EMAIL_SUBJECT } from '@impler/shared';
import { SCREENS, EMAIL_SUBJECT, UserRolesEnum } from '@impler/shared';
import { AuthService } from 'app/auth/services/auth.service';
import { RegisterUserCommand } from './register-user.command';
import { generateVerificationCode } from '@shared/helpers/common.helper';
Expand All @@ -29,6 +29,7 @@ export class RegisterUser {

const passwordHash = await bcrypt.hash(command.password, 10);
const verificationCode = generateVerificationCode();
const isEmailVerified = command.invitationId ? true : this.emailService.isConnected() ? false : true;

const user = await this.userRepository.create({
email: command.email,
Expand All @@ -37,17 +38,25 @@ export class RegisterUser {
password: passwordHash,
signupMethod: LEAD_SIGNUP_USING.EMAIL,
verificationCode,
isEmailVerified: this.emailService.isConnected() ? false : true,
isEmailVerified,
});

const token = this.authService.getSignedToken({
_id: user._id,
email: user.email,
firstName: user.firstName,
lastName: user.lastName,
role: user.role as UserRolesEnum,
isEmailVerified: user.isEmailVerified,
});

if (command.invitationId) {
return {
screen: SCREENS.INVIATAION,
token,
};
}

if (this.emailService.isConnected()) {
const emailContents = this.emailService.getEmailContent({
type: 'VERIFICATION_EMAIL',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Injectable } from '@nestjs/common';
import { UserRepository } from '@impler/dal';
import { EMAIL_SUBJECT } from '@impler/shared';
import { EMAIL_SUBJECT, UserRolesEnum } from '@impler/shared';
import { EmailService } from '@impler/services';
import { UpdateUserCommand } from './update-user.command';
import { AuthService } from 'app/auth/services/auth.service';
Expand Down Expand Up @@ -56,6 +56,7 @@ export class UpdateUser {
email: user.email,
firstName: user.firstName,
lastName: user.lastName,
role: user.role as UserRolesEnum,
isEmailVerified: user.isEmailVerified,
});

Expand Down
Loading

0 comments on commit f1f9958

Please sign in to comment.