Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/authentication/authentication.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ const providers: Provider[] = [
TwilioImplModule,
HttpModule,
],
providers: providers,
providers,
controllers: [GoogleAuthController],
})
export class UserAuthModule {}
6 changes: 3 additions & 3 deletions src/authentication/service/google.service.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common';
import { InvalidPayloadException } from '../exception/userauth.exception';
import User from '../../authorization/entity/user.entity';
import { GoogleUserSchema } from '../validation/user.auth.schema.validation';
import UserService from '../../authorization/service/user.service';
import { UserServiceInterface } from '../../authorization/service/user.service.interface';
import { AuthenticationHelper } from '../authentication.helper';
import { GoogleLoginUser } from '../passport/googleStrategy';

@Injectable()
export class GoogleAuthService {
constructor(
private userService: UserService,
@Inject(UserServiceInterface) private userService: UserServiceInterface,
private authenticationHelper: AuthenticationHelper,
) {}
private async validateInput(
Expand Down
6 changes: 3 additions & 3 deletions src/authentication/service/otp.auth.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common';
import User from '../../authorization/entity/user.entity';
import { UserNotFoundException } from '../../authorization/exception/user.exception';
import UserService from '../../authorization/service/user.service';
import { UserServiceInterface } from '../../authorization/service/user.service.interface';
import {
Status,
TokenResponse,
Expand All @@ -20,7 +20,7 @@ import { TokenService } from './token.service';
@Injectable()
export default class OTPAuthService implements Authenticatable {
constructor(
private userService: UserService,
@Inject(UserServiceInterface) private userService: UserServiceInterface,
private tokenService: TokenService,
private otpService: OTPVerifiable,
) {}
Expand Down
6 changes: 3 additions & 3 deletions src/authentication/service/password.auth.service.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { DataSource } from 'typeorm';
import User from '../../authorization/entity/user.entity';
import {
PasswordAlreadySetException,
UserNotFoundException,
} from '../../authorization/exception/user.exception';
import UserService from '../../authorization/service/user.service';
import { UserServiceInterface } from '../../authorization/service/user.service.interface';
import {
InviteTokenResponse,
Status,
Expand All @@ -29,7 +29,7 @@ import { TokenService } from './token.service';
@Injectable()
export default class PasswordAuthService implements Authenticatable {
constructor(
private userService: UserService,
@Inject(UserServiceInterface) private userService: UserServiceInterface,
private tokenService: TokenService,
private authenticationHelper: AuthenticationHelper,
private dataSource: DataSource,
Expand Down
6 changes: 3 additions & 3 deletions src/authentication/service/token.service.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { Inject, Injectable, UnauthorizedException } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import User from '../../authorization/entity/user.entity';
import {
InviteTokenAlreadyRevokedException,
PasswordAlreadySetException,
} from '../../authorization/exception/user.exception';
import UserService from '../../authorization/service/user.service';
import { UserServiceInterface } from '../../authorization/service/user.service.interface';
import {
InviteTokenResponse,
TokenResponse,
Expand All @@ -15,7 +15,7 @@ import { AuthenticationHelper } from '../authentication.helper';
@Injectable()
export class TokenService {
constructor(
private userService: UserService,
@Inject(UserServiceInterface) private userService: UserServiceInterface,
private authenticationHelper: AuthenticationHelper,
private configService: ConfigService,
) {}
Expand Down
14 changes: 11 additions & 3 deletions src/authorization/authorization.guard.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import {
CanActivate,
ExecutionContext,
Inject,
Injectable,
} from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { GqlExecutionContext } from '@nestjs/graphql';
import UserService from './service/user.service';
import { UserServiceInterface } from './service/user.service.interface';

@Injectable()
export class AuthorizationGaurd implements CanActivate {
constructor(private userService: UserService, private reflector: Reflector) {}
constructor(
@Inject(UserServiceInterface) private userService: UserServiceInterface,
private reflector: Reflector,
) {}
public async canActivate(context: ExecutionContext): Promise<boolean> {
const ctx = GqlExecutionContext.create(context).getContext();
const permissionsRequired = this.reflector.get<string[]>(
Expand Down
23 changes: 18 additions & 5 deletions src/authorization/authorization.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,10 @@ import { RoleServiceInterface } from './service/role.service.interface';
import RoleCacheService from './service/rolecache.service';
import { RoleCacheServiceInterface } from './service/rolecache.service.interface';
import SearchService from './service/search.service';
import UserService from './service/user.service';
import UserCacheService from './service/usercache.service';
import { UserService } from './service/user.service';
import { UserServiceInterface } from './service/user.service.interface';
import { UserCacheService } from './service/usercache.service';
import { UserCacheServiceInterface } from './service/usercache.service.interface';

@Module({
imports: [
Expand All @@ -69,11 +71,9 @@ import UserCacheService from './service/usercache.service';
providers: [
GroupResolver,
PermissionResolver,
UserService,
UserResolver,
EntityResolver,
RedisCacheService,
UserCacheService,
AuthenticationHelper,
ConfigService,
RoleResolver,
Expand Down Expand Up @@ -117,7 +117,20 @@ import UserCacheService from './service/usercache.service';
provide: GroupCacheServiceInterface,
useClass: GroupCacheService,
},
{
provide: UserServiceInterface,
useClass: UserService,
},
{
provide: UserCacheServiceInterface,
useClass: UserCacheService,
},
],
exports: [
{
provide: UserServiceInterface,
useClass: UserService,
},
],
exports: [UserService],
})
export class AuthorizationModule {}
8 changes: 5 additions & 3 deletions src/authorization/resolver/user.resolver.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { UseGuards } from '@nestjs/common';
import { Inject, UseGuards } from '@nestjs/common';
import { ParseUUIDPipe } from '@nestjs/common/pipes';
import {
Args,
Expand All @@ -24,12 +24,14 @@ import {
import ValidationPipe from '../../validation/validation.pipe';
import { PermissionsType } from '../constants/authorization.constants';
import { Permissions } from '../permissions.decorator';
import UserService from '../service/user.service';
import { UserServiceInterface } from '../service/user.service.interface';
import * as UserSchema from '../validation/user.validation.schema';

@Resolver('User')
export class UserResolver {
constructor(private userService: UserService) {}
constructor(
@Inject(UserServiceInterface) private userService: UserServiceInterface,
) {}

@Permissions(PermissionsType.ViewUser)
@Query()
Expand Down
5 changes: 3 additions & 2 deletions src/authorization/service/group.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import { UserGroupRepository } from '../repository/userGroup.repository';
import { GroupServiceInterface } from './group.service.interface';
import { GroupCacheServiceInterface } from './groupcache.service.interface';
import SearchService from './search.service';
import UserCacheService from './usercache.service';
import { UserCacheServiceInterface } from './usercache.service.interface';

@Injectable()
export class GroupService implements GroupServiceInterface {
Expand All @@ -47,7 +47,8 @@ export class GroupService implements GroupServiceInterface {
private dataSource: DataSource,
@Inject(GroupCacheServiceInterface)
private groupCacheService: GroupCacheServiceInterface,
private userCacheService: UserCacheService,
@Inject(UserCacheServiceInterface)
private userCacheService: UserCacheServiceInterface,
private searchService: SearchService,
) {}

Expand Down
66 changes: 66 additions & 0 deletions src/authorization/service/user.service.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import User from '../entity/user.entity';
import {
OperationType,
UpdateUserGroupInput,
UpdateUserInput,
UpdateUserPermissionInput,
UserInputFilter,
} from '../../schema/graphql.schema';
import Group from '../entity/group.entity';
import Permission from '../entity/permission.entity';

export interface UserServiceInterface {
getAllUsers(input?: UserInputFilter): Promise<[User[], number]>;

getUserById(id: string): Promise<User>;

createUser(user: User): Promise<User>;

updateUser(id: string, user: UpdateUserInput): Promise<User>;

updateUserGroups(id: string, user: UpdateUserGroupInput): Promise<Group[]>;

getUserGroups(id: string): Promise<Group[]>;

updateUserPermissions(
id: string,
request: UpdateUserPermissionInput,
): Promise<Permission[]>;

getUserPermissions(id: string): Promise<Permission[]>;

deleteUser(id: string): Promise<User>;

getAllUserpermissionIds(id: string): Promise<Set<string>>;

permissionsOfUser(id: string): Promise<Permission[]>;

verifyUserPermissions(
id: string,
permissionsToVerify: string[],
operation?: OperationType,
): Promise<boolean>;

verifyDuplicateUser(
email?: string | undefined,
phone?: string | undefined,
): Promise<{ existingUserDetails?: User | null; duplicate: string }>;

getUserDetailsByEmailOrPhone(
email?: string | undefined,
phone?: string | undefined,
): Promise<any>;

getUserDetailsByUsername(
email?: string | undefined,
phone?: string | undefined,
): Promise<User | null>;

updateField(id: string, field: string, value: any): Promise<User>;

getActiveUserByPhoneNumber(phone: string): Promise<User | null>;

setOtpSecret(user: User, twoFASecret: string): Promise<void>;
}

export const UserServiceInterface = Symbol('UserServiceInterface');
10 changes: 6 additions & 4 deletions src/authorization/service/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,19 @@ import { GroupCacheServiceInterface } from './groupcache.service.interface';
import { PermissionCacheServiceInterface } from './permissioncache.service.interface';
import { RoleCacheServiceInterface } from './rolecache.service.interface';
import SearchService from './search.service';
import UserCacheService from './usercache.service';
import { UserServiceInterface } from './user.service.interface';
import { UserCacheServiceInterface } from './usercache.service.interface';

@Injectable()
export default class UserService {
export class UserService implements UserServiceInterface {
constructor(
private userRepository: UserRepository,
private userGroupRepository: UserGroupRepository,
private groupRepository: GroupRepository,
private userPermissionRepository: UserPermissionRepository,
private permissionRepository: PermissionRepository,
private userCacheService: UserCacheService,
@Inject(UserCacheServiceInterface)
private userCacheService: UserCacheServiceInterface,
@Inject(GroupCacheServiceInterface)
private groupCacheService: GroupCacheServiceInterface,
@Inject(PermissionCacheServiceInterface)
Expand Down Expand Up @@ -263,7 +265,7 @@ export default class UserService {
return allPermissionsOfUser;
}

public async permissionsOfUser(id: string) {
public async permissionsOfUser(id: string): Promise<Permission[]> {
const setOfPermissions: Set<string> = await this.getAllUserpermissionIds(
id,
);
Expand Down
11 changes: 11 additions & 0 deletions src/authorization/service/usercache.service.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export interface UserCacheServiceInterface {
getUserGroupsByUserId(userId: string): Promise<string[]>;

getUserPermissionsByUserId(userId: string): Promise<string[]>;

invalidateUserPermissionsCache(userId: string): Promise<void>;

invalidateUserGroupsCache(userId: string): Promise<void>;
}

export const UserCacheServiceInterface = Symbol('UserCacheServiceInterface');
3 changes: 2 additions & 1 deletion src/authorization/service/usercache.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import { RedisCacheService } from '../../cache/redis-cache/redis-cache.service';
import { UserRepository } from '../repository/user.repository';
import { UserGroupRepository } from '../repository/userGroup.repository';
import { UserPermissionRepository } from '../repository/userPermission.repository';
import { UserCacheServiceInterface } from './usercache.service.interface';

@Injectable()
export default class UserCacheService {
export class UserCacheService implements UserCacheServiceInterface {
constructor(
private cacheManager: RedisCacheService,
private userGroupRepository: UserGroupRepository,
Expand Down
24 changes: 12 additions & 12 deletions test/authentication/resolver/userauth.resolver.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Test, TestingModule } from '@nestjs/testing';
import { ConfigService } from '@nestjs/config';
import * as request from 'supertest';
import { INestApplication } from '@nestjs/common';
import UserService from '../../../src/authorization/service/user.service';
import { UserServiceInterface } from '../../../src/authorization/service/user.service.interface';
import Substitute, { Arg } from '@fluffy-spoon/substitute';
import User from '../../../src/authorization/entity/user.entity';
import { UserResolver } from '../../../src/authorization/resolver/user.resolver';
Expand All @@ -18,12 +19,11 @@ import {
} from '../../../src/schema/graphql.schema';
import UserAuthResolver from '../../../src/authentication/resolver/user.auth.resolver';
import { AuthenticationHelper } from '../../../src/authentication/authentication.helper';
import { ConfigService } from '@nestjs/config';
import UserCacheService from '../../../src/authorization/service/usercache.service';
import { RedisCacheService } from '../../../src/cache/redis-cache/redis-cache.service';
import PasswordAuthService from '../../../src/authentication/service/password.auth.service';
import OTPAuthService from '../../../src/authentication/service/otp.auth.service';
import { TokenService } from '../../../src/authentication/service/token.service';
import { UserCacheServiceInterface } from '../../../src/authorization/service/usercache.service.interface';

const users: User[] = [
{
Expand All @@ -40,11 +40,11 @@ const users: User[] = [

const gql = '/graphql';

const userService = Substitute.for<UserService>();
const userService = Substitute.for<UserServiceInterface>();
const passwordAuthService = Substitute.for<PasswordAuthService>();
const otpAuthService = Substitute.for<OTPAuthService>();
const tokenService = Substitute.for<TokenService>();
const userCacheService = Substitute.for<UserCacheService>();
const userCacheService = Substitute.for<UserCacheServiceInterface>();
const redisCacheService = Substitute.for<RedisCacheService>();

describe('Userauth Module', () => {
Expand All @@ -60,13 +60,13 @@ describe('Userauth Module', () => {
UserAuthResolver,
ConfigService,
AuthenticationHelper,
{ provide: 'UserService', useValue: userService },
{ provide: 'TokenService', useValue: tokenService },
{ provide: 'PasswordAuthService', useValue: passwordAuthService },
{ provide: 'OTPAuthService', useValue: otpAuthService },
{ provide: 'ConfigService', useValue: configService },
{ provide: 'UserCacheService', useValue: userCacheService },
{ provide: 'RedisCacheService', useValue: redisCacheService },
{ provide: UserServiceInterface, useValue: userService },
{ provide: TokenService, useValue: tokenService },
{ provide: PasswordAuthService, useValue: passwordAuthService },
{ provide: OTPAuthService, useValue: otpAuthService },
{ provide: ConfigService, useValue: configService },
{ provide: UserCacheServiceInterface, useValue: userCacheService },
{ provide: RedisCacheService, useValue: redisCacheService },
],
}).compile();
authenticationHelper = moduleFixture.get<AuthenticationHelper>(
Expand Down
Loading