mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-14 03:40:31 +00:00
add server to monorepo.
This commit is contained in:
146
packages/server/src/services/InviteUsers/AcceptInviteUser.ts
Normal file
146
packages/server/src/services/InviteUsers/AcceptInviteUser.ts
Normal file
@@ -0,0 +1,146 @@
|
||||
import { Service, Inject } from 'typedi';
|
||||
import moment from 'moment';
|
||||
import { ServiceError } from '@/exceptions';
|
||||
import { Invite, SystemUser, Tenant } from '@/system/models';
|
||||
import { hashPassword } from 'utils';
|
||||
import TenancyService from '@/services/Tenancy/TenancyService';
|
||||
import InviteUsersMailMessages from '@/services/InviteUsers/InviteUsersMailMessages';
|
||||
import events from '@/subscribers/events';
|
||||
import {
|
||||
IAcceptInviteEventPayload,
|
||||
IInviteUserInput,
|
||||
ICheckInviteEventPayload,
|
||||
IUserInvite,
|
||||
} from '@/interfaces';
|
||||
import TenantsManagerService from '@/services/Tenancy/TenantsManager';
|
||||
import { ERRORS } from './constants';
|
||||
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
||||
|
||||
@Service()
|
||||
export default class AcceptInviteUserService {
|
||||
@Inject()
|
||||
eventPublisher: EventPublisher;
|
||||
|
||||
@Inject()
|
||||
tenancy: TenancyService;
|
||||
|
||||
@Inject('logger')
|
||||
logger: any;
|
||||
|
||||
@Inject()
|
||||
mailMessages: InviteUsersMailMessages;
|
||||
|
||||
@Inject('repositories')
|
||||
sysRepositories: any;
|
||||
|
||||
@Inject()
|
||||
tenantsManager: TenantsManagerService;
|
||||
|
||||
/**
|
||||
* Accept the received invite.
|
||||
* @param {string} token
|
||||
* @param {IInviteUserInput} inviteUserInput
|
||||
* @throws {ServiceErrors}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
public async acceptInvite(
|
||||
token: string,
|
||||
inviteUserDTO: IInviteUserInput
|
||||
): Promise<void> {
|
||||
// Retrieve the invite token or throw not found error.
|
||||
const inviteToken = await this.getInviteTokenOrThrowError(token);
|
||||
|
||||
// Validates the user phone number.
|
||||
await this.validateUserPhoneNumberNotExists(inviteUserDTO.phoneNumber);
|
||||
|
||||
// Hash the given password.
|
||||
const hashedPassword = await hashPassword(inviteUserDTO.password);
|
||||
|
||||
// Retrieve the system user.
|
||||
const user = await SystemUser.query().findOne('email', inviteToken.email);
|
||||
|
||||
// Sets the invited user details after invite accepting.
|
||||
const systemUser = await SystemUser.query().updateAndFetchById(
|
||||
inviteToken.userId,
|
||||
{
|
||||
...inviteUserDTO,
|
||||
inviteAcceptedAt: moment().format('YYYY-MM-DD'),
|
||||
password: hashedPassword,
|
||||
}
|
||||
);
|
||||
// Clear invite token by the given user id.
|
||||
await this.clearInviteTokensByUserId(inviteToken.userId);
|
||||
|
||||
// Triggers `onUserAcceptInvite` event.
|
||||
await this.eventPublisher.emitAsync(events.inviteUser.acceptInvite, {
|
||||
inviteToken,
|
||||
user: systemUser,
|
||||
inviteUserDTO,
|
||||
} as IAcceptInviteEventPayload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the given invite token.
|
||||
* @param {string} token - the given token string.
|
||||
* @throws {ServiceError}
|
||||
*/
|
||||
public async checkInvite(
|
||||
token: string
|
||||
): Promise<{ inviteToken: IUserInvite; orgName: object }> {
|
||||
const inviteToken = await this.getInviteTokenOrThrowError(token);
|
||||
|
||||
// Find the tenant that associated to the given token.
|
||||
const tenant = await Tenant.query()
|
||||
.findById(inviteToken.tenantId)
|
||||
.withGraphFetched('metadata');
|
||||
|
||||
// Triggers `onUserCheckInvite` event.
|
||||
await this.eventPublisher.emitAsync(events.inviteUser.checkInvite, {
|
||||
inviteToken,
|
||||
tenant,
|
||||
} as ICheckInviteEventPayload);
|
||||
|
||||
return { inviteToken, orgName: tenant.metadata.name };
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve invite model from the given token or throw error.
|
||||
* @param {string} token - Then given token string.
|
||||
* @throws {ServiceError}
|
||||
* @returns {Invite}
|
||||
*/
|
||||
private getInviteTokenOrThrowError = async (
|
||||
token: string
|
||||
): Promise<IUserInvite> => {
|
||||
const inviteToken = await Invite.query()
|
||||
.modify('notExpired')
|
||||
.findOne('token', token);
|
||||
|
||||
if (!inviteToken) {
|
||||
throw new ServiceError(ERRORS.INVITE_TOKEN_INVALID);
|
||||
}
|
||||
return inviteToken;
|
||||
};
|
||||
|
||||
/**
|
||||
* Validate the given user email and phone number uniquine.
|
||||
* @param {IInviteUserInput} inviteUserInput
|
||||
*/
|
||||
private validateUserPhoneNumberNotExists = async (
|
||||
phoneNumber: string
|
||||
): Promise<void> => {
|
||||
const foundUser = await SystemUser.query().findOne({ phoneNumber });
|
||||
|
||||
if (foundUser) {
|
||||
throw new ServiceError(ERRORS.PHONE_NUMBER_EXISTS);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear invite tokens of the given user id.
|
||||
* @param {number} userId - User id.
|
||||
*/
|
||||
private clearInviteTokensByUserId = async (userId: number) => {
|
||||
await Invite.query().where('user_id', userId).delete();
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user