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
Original file line number Diff line number Diff line change
Expand Up @@ -5,58 +5,62 @@ import { InvitationInCompanyEntity } from '../invitation-in-company.entity.js';
import { IInvitationInCompanyRepository } from './invitation-repository.interface.js';

export const invitationInCompanyCustomRepositoryExtension: IInvitationInCompanyRepository = {
async createOrUpdateInvitationInCompany(
companyInfo: CompanyInfoEntity,
groupId: string | null,
inviterId: string,
newUserEmail: string,
invitedUserRole: UserRoleEnum,
): Promise<InvitationInCompanyEntity> {
const qb = this.createQueryBuilder('invitation_in_company')
.leftJoinAndSelect('invitation_in_company.company', 'company')
.where('company.id = :companyId', { companyId: companyInfo.id })
.andWhere('invitation_in_company.invitedUserEmail = :newUserEmail', { newUserEmail: newUserEmail?.toLowerCase() });
const foundInvitation = await qb.getOne();
if (foundInvitation) {
await this.remove(foundInvitation);
}
const newInvitation = new InvitationInCompanyEntity();
newInvitation.verification_string = Encryptor.generateRandomString();
newInvitation.company = companyInfo;
newInvitation.groupId = groupId ? groupId : null;
newInvitation.inviterId = inviterId;
newInvitation.invitedUserEmail = newUserEmail?.toLowerCase();
newInvitation.role = invitedUserRole;
return await this.save(newInvitation);
},
async createOrUpdateInvitationInCompany(
companyInfo: CompanyInfoEntity,
groupId: string | null,
inviterId: string,
newUserEmail: string,
invitedUserRole: UserRoleEnum,
): Promise<{ entity: InvitationInCompanyEntity; rawToken: string }> {
const qb = this.createQueryBuilder('invitation_in_company')
.leftJoinAndSelect('invitation_in_company.company', 'company')
.where('company.id = :companyId', { companyId: companyInfo.id })
.andWhere('invitation_in_company.invitedUserEmail = :newUserEmail', {
newUserEmail: newUserEmail?.toLowerCase(),
});
const foundInvitation = await qb.getOne();
if (foundInvitation) {
await this.remove(foundInvitation);
}
const rawToken = Encryptor.generateRandomString();
const newInvitation = new InvitationInCompanyEntity();
newInvitation.verification_string = Encryptor.hashVerificationToken(rawToken);
newInvitation.company = companyInfo;
newInvitation.groupId = groupId ? groupId : null;
newInvitation.inviterId = inviterId;
newInvitation.invitedUserEmail = newUserEmail?.toLowerCase();
newInvitation.role = invitedUserRole;
const entity = await this.save(newInvitation);
return { entity, rawToken };
},

async deleteOldInvitationsInCompany(companyId: string): Promise<void> {
const qb = this.createQueryBuilder('invitation_in_company')
.leftJoinAndSelect('invitation_in_company.company', 'company')
.where('company.id = :companyId', { companyId })
.andWhere("invitation_in_company.createdAt < NOW() - INTERVAL '1 day'");
const foundInvitations = await qb.getMany();
if (foundInvitations.length) {
await this.remove(foundInvitations);
}
},
async deleteOldInvitationsInCompany(companyId: string): Promise<void> {
const qb = this.createQueryBuilder('invitation_in_company')
.leftJoinAndSelect('invitation_in_company.company', 'company')
.where('company.id = :companyId', { companyId })
.andWhere("invitation_in_company.createdAt < NOW() - INTERVAL '1 day'");
const foundInvitations = await qb.getMany();
if (foundInvitations.length) {
await this.remove(foundInvitations);
}
},

async findNonExpiredInvitationInCompanyWithUsersByVerificationString(
verificationString: string,
): Promise<InvitationInCompanyEntity> {
const qb = this.createQueryBuilder('invitation_in_company')
.leftJoinAndSelect('invitation_in_company.company', 'company')
.leftJoinAndSelect('company.users', 'users')
.where("invitation_in_company.createdAt > NOW() - INTERVAL '1 day'")
.where('invitation_in_company.verification_string = :verificationString', { verificationString });
return await qb.getOne();
},
async findNonExpiredInvitationInCompanyWithUsersByVerificationString(
verificationString: string,
): Promise<InvitationInCompanyEntity> {
const qb = this.createQueryBuilder('invitation_in_company')
.leftJoinAndSelect('invitation_in_company.company', 'company')
.leftJoinAndSelect('company.users', 'users')
.where("invitation_in_company.createdAt > NOW() - INTERVAL '1 day'")
.where('invitation_in_company.verification_string = :verificationString', { verificationString });
return await qb.getOne();
},

async countNonExpiredInvitationsInCompany(companyId: string): Promise<number> {
const qb = this.createQueryBuilder('invitation_in_company')
.leftJoin('invitation_in_company.company', 'company')
.where('company.id = :companyId', { companyId })
.andWhere("invitation_in_company.createdAt > NOW() - INTERVAL '1 day'");
return await qb.getCount();
},
async countNonExpiredInvitationsInCompany(companyId: string): Promise<number> {
const qb = this.createQueryBuilder('invitation_in_company')
.leftJoin('invitation_in_company.company', 'company')
.where('company.id = :companyId', { companyId })
.andWhere("invitation_in_company.createdAt > NOW() - INTERVAL '1 day'");
return await qb.getCount();
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@ import { CompanyInfoEntity } from '../../company-info.entity.js';
import { InvitationInCompanyEntity } from '../invitation-in-company.entity.js';

export interface IInvitationInCompanyRepository {
createOrUpdateInvitationInCompany(
companyInfo: CompanyInfoEntity,
groupId: string | null,
inviterId: string,
newUserEmail: string,
invitedUserRole: UserRoleEnum,
): Promise<InvitationInCompanyEntity>;
createOrUpdateInvitationInCompany(
companyInfo: CompanyInfoEntity,
groupId: string | null,
inviterId: string,
newUserEmail: string,
invitedUserRole: UserRoleEnum,
): Promise<{ entity: InvitationInCompanyEntity; rawToken: string }>;

deleteOldInvitationsInCompany(companyId: string): Promise<void>;
deleteOldInvitationsInCompany(companyId: string): Promise<void>;

findNonExpiredInvitationInCompanyWithUsersByVerificationString(
verificationString: string,
): Promise<InvitationInCompanyEntity>;
findNonExpiredInvitationInCompanyWithUsersByVerificationString(
verificationString: string,
): Promise<InvitationInCompanyEntity>;

countNonExpiredInvitationsInCompany(companyId: string): Promise<number>;
countNonExpiredInvitationsInCompany(companyId: string): Promise<number>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,33 @@ import { IGlobalDatabaseContext } from '../../../common/application/global-datab
import { BaseType } from '../../../common/data-injection.tokens.js';
import { SuccessResponse } from '../../../microservices/saas-microservice/data-structures/common-responce.ds.js';
import { ICheckVerificationLinkAvailable } from './company-info-use-cases.interface.js';
import { Encryptor } from '../../../helpers/encryption/encryptor.js';

@Injectable()
export class CheckIsVerificationLinkAvailable
extends AbstractUseCase<string, SuccessResponse>
implements ICheckVerificationLinkAvailable
extends AbstractUseCase<string, SuccessResponse>
implements ICheckVerificationLinkAvailable
{
constructor(
@Inject(BaseType.GLOBAL_DB_CONTEXT)
protected _dbContext: IGlobalDatabaseContext,
) {
super();
}
constructor(
@Inject(BaseType.GLOBAL_DB_CONTEXT)
protected _dbContext: IGlobalDatabaseContext,
) {
super();
}

protected async implementation(verificationString: string): Promise<SuccessResponse> {
const foundInvitation =
await this._dbContext.invitationInCompanyRepository.findNonExpiredInvitationInCompanyWithUsersByVerificationString(
verificationString,
);
if (!foundInvitation) {
return {
success: false,
};
}
return {
success: true,
};
}
protected async implementation(verificationString: string): Promise<SuccessResponse> {
const hashedToken = Encryptor.hashVerificationToken(verificationString);
const foundInvitation =
await this._dbContext.invitationInCompanyRepository.findNonExpiredInvitationInCompanyWithUsersByVerificationString(
hashedToken,
);
if (!foundInvitation) {
return {
success: false,
};
}
return {
success: true,
};
}
}
Loading
Loading