src/user/user.controller.ts
api/v1/user
Methods |
|
| Async assignInvestorToNewDealer | |||||||||
assignInvestorToNewDealer(id: string, assignNewDealerDto: AssignNewDealerDto)
|
|||||||||
Decorators :
@UseGuards(new RolesAuthGuard())
|
|||||||||
|
Defined in src/user/user.controller.ts:313
|
|||||||||
|
Parameters :
Returns :
unknown
|
| Async createWallet | ||||||||||||
createWallet(id: string, request: AuthRequest, updateWalletDto: UpdateWalletDto)
|
||||||||||||
Decorators :
@UseGuards(new RolesAuthGuard())
|
||||||||||||
|
Defined in src/user/user.controller.ts:345
|
||||||||||||
|
Parameters :
Returns :
any
|
| Async findAll | |||||||||
findAll(request: AuthRequest, filterUserDTO: FilterUserDto)
|
|||||||||
Decorators :
@UseGuards(new RolesAuthGuard())
|
|||||||||
|
Defined in src/user/user.controller.ts:66
|
|||||||||
|
Parameters :
Returns :
unknown
|
| Async findOne | |||||||||
findOne(request: AuthRequest, id: string)
|
|||||||||
Decorators :
@UseGuards(new RolesAuthGuard())
|
|||||||||
|
Defined in src/user/user.controller.ts:163
|
|||||||||
|
Parameters :
Returns :
unknown
|
| Async findOneWithOrderBook | ||||||||||||
findOneWithOrderBook(request: AuthRequest, investorId: string, filterOrderDto: FilterOrderDto)
|
||||||||||||
Decorators :
@UseGuards(new RolesAuthGuard())
|
||||||||||||
|
Defined in src/user/user.controller.ts:186
|
||||||||||||
|
Parameters :
Returns :
unknown
|
| Async getBalance | |||||||||
getBalance(request: AuthRequest, instrumentId: string)
|
|||||||||
Decorators :
@UseGuards(new RolesAuthGuard())
|
|||||||||
|
Defined in src/user/user.controller.ts:137
|
|||||||||
|
Parameters :
Returns :
unknown
|
| Async getEditableForm | |||||||||
getEditableForm(request: AuthRequest, dealerConfigDto: DealerConfigDto)
|
|||||||||
Decorators :
@UseInterceptors(CustomCacheInterceptor)
|
|||||||||
|
Defined in src/user/user.controller.ts:482
|
|||||||||
|
Parameters :
Returns :
unknown
|
| Async getFundDetailsSubscription | ||||||||||||
getFundDetailsSubscription(request: AuthRequest, userId: string, fundId: string)
|
||||||||||||
Decorators :
@UseInterceptors(CustomCacheInterceptor)
|
||||||||||||
|
Defined in src/user/user.controller.ts:222
|
||||||||||||
|
Parameters :
Returns :
unknown
|
| Async getOnboardConfig | |||||||||
getOnboardConfig(request: AuthRequest, dealerConfigDto: DealerConfigDto)
|
|||||||||
Decorators :
@UseInterceptors(CustomCacheInterceptor)
|
|||||||||
|
Defined in src/user/user.controller.ts:457
|
|||||||||
|
Parameters :
Returns :
unknown
|
| Async getOnchainFieldMapping |
getOnchainFieldMapping()
|
Decorators :
@UseInterceptors(CustomCacheInterceptor)
|
|
Defined in src/user/user.controller.ts:507
|
|
Returns :
unknown
|
| Async getRegisterForm |
getRegisterForm()
|
Decorators :
@CacheTTL(1000000)
|
|
Defined in src/user/user.controller.ts:440
|
|
Returns :
unknown
|
| Async getWallets | |||||||||
getWallets(request: AuthRequest, id: string)
|
|||||||||
Decorators :
@UseGuards(new RolesAuthGuard())
|
|||||||||
|
Defined in src/user/user.controller.ts:360
|
|||||||||
|
Parameters :
Returns :
unknown
|
| Async getWalletsByAddress | ||||||
getWalletsByAddress(address: string)
|
||||||
Decorators :
@UseGuards(new RolesAuthGuard())
|
||||||
|
Defined in src/user/user.controller.ts:387
|
||||||
|
Parameters :
Returns :
unknown
|
| Async myProfile | ||||||
myProfile(request: AuthRequest)
|
||||||
Decorators :
@UseGuards(undefined)
|
||||||
|
Defined in src/user/user.controller.ts:120
|
||||||
|
Parameters :
Returns :
unknown
|
| Async subscribeUser | ||||||||||||
subscribeUser(id: string, request: AuthRequest, subscribeUserDto: SubscribeUserDto)
|
||||||||||||
Decorators :
@UseGuards(new RolesAuthGuard())
|
||||||||||||
|
Defined in src/user/user.controller.ts:274
|
||||||||||||
|
Parameters :
Returns :
unknown
|
| Async update | ||||||||||||
update(id: string, request: AuthRequest, updateUserDto: UpdateUserDto)
|
||||||||||||
Decorators :
@UseGuards(new RolesAuthGuard())
|
||||||||||||
|
Defined in src/user/user.controller.ts:243
|
||||||||||||
|
Parameters :
Returns :
unknown
|
| Async updateOnboardEditableFields | |||||||||
updateOnboardEditableFields(request: AuthRequest, onboardEditableForm: OnboardEditableFormDto)
|
|||||||||
Decorators :
@UseGuards(new RolesAuthGuard())
|
|||||||||
|
Defined in src/user/user.controller.ts:518
|
|||||||||
|
Parameters :
Returns :
unknown
|
| Async updateWalletLabel | |||||||||||||||
updateWalletLabel(request: AuthRequest, id: string, address: string, updateWalletDto: UpdateWalletDto)
|
|||||||||||||||
Decorators :
@UseGuards(new RolesAuthGuard())
|
|||||||||||||||
|
Defined in src/user/user.controller.ts:397
|
|||||||||||||||
|
Parameters :
Returns :
unknown
|
import { UpdateWalletDto } from "./../wallet/dto/update-wallet.dto";
import { OnboardEditableFormDto } from "./dto/onboard-config.dto";
import {
BadRequestException,
Body,
CacheInterceptor,
CacheTTL,
Controller,
Get,
Inject,
Param,
Post,
Put,
Query,
Req,
ServiceUnavailableException,
UnauthorizedException,
UseGuards,
UseInterceptors,
} from "@nestjs/common";
import { RolesAuthGuard } from "src/auth/guards/roles-auth.guard";
import {
AuthRequest,
ContractName,
EndUserRoles,
IGetInvestorsIdByInstrumentQuery,
TransactionNames,
} from "src/common/interfaces";
import { UpdateUserDto } from "./dto/update-user.dto";
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { UserService } from "./user.service";
import { WalletService } from "src/wallet/wallet.service";
import { FilterUserDto } from "./dto/filter-user.dto";
import { SubscribeUserDto } from "./dto/subscribe-user.dto";
import { AuthGuard } from "@nestjs/passport";
import {
apolloClient,
getContractByName,
getInvestorsIdByInstrumentQuery,
transactionSubmitter,
} from "src/common/provider";
import { DEFAULT_LIBRE_DEALER, Roles } from "src/common/constants";
import { AssignNewDealerDto } from "./dto/assign-new-dealer-user.dto";
import { decodeBytes32String, encodeBytes32String, formatEther } from "ethers";
import { ApolloQueryResult } from "@apollo/client";
import { UserCmsService } from "./user.cms.service";
import { UserOrderbookService } from "./user.orderbook.service";
import { FilterOrderDto } from "src/orderbook/dto/filter-order.dto";
import { DealerConfigDto } from "./dto/dealer-config.dto";
import { CustomCacheInterceptor } from "src/interceptor/cache.interceptor";
@Controller("api/v1/user")
export class UserController {
@Inject(WalletService)
private readonly walletService: WalletService;
@Inject(UserCmsService)
private readonly userCmsService: UserCmsService;
@Inject(UserOrderbookService)
private readonly userOrderbookService: UserOrderbookService;
constructor(private readonly userService: UserService) {}
@UseGuards(new RolesAuthGuard(["admin", "dealer"]))
@Get("/")
async findAll(
@Req() request: AuthRequest,
@Query() filterUserDTO: FilterUserDto,
) {
try {
let newFilterUserDto = filterUserDTO;
if (request.user.role === EndUserRoles.dealer) {
newFilterUserDto = {
...filterUserDTO,
onboardByEmail: request.user.email,
};
}
if (filterUserDTO.instrumentId) {
const whitelistInfo: ApolloQueryResult<IGetInvestorsIdByInstrumentQuery> =
await apolloClient.query({
query: getInvestorsIdByInstrumentQuery,
variables: {
instrumentId: encodeBytes32String(filterUserDTO.instrumentId),
},
});
const unconfirmedRedemptionAmountById: Record<string, string> = {};
newFilterUserDto = {
...newFilterUserDto,
_id: {
$in: whitelistInfo.data.whitelistInfos.map(
({ id, unConfirmedRedeemedAmount }) => {
const decodedId = decodeBytes32String(id);
unconfirmedRedemptionAmountById[decodedId] = formatEther(
unConfirmedRedeemedAmount || 0,
);
return decodedId;
},
),
},
};
return await this.userService.findUsersByFilterByUsersBalance(
newFilterUserDto,
unconfirmedRedemptionAmountById,
);
}
return await this.userService.findUsersByFilter(newFilterUserDto, true);
} catch (error) {
console.error(error);
throw new ServiceUnavailableException(error);
}
}
@UseGuards(AuthGuard("jwt"))
@UseInterceptors(CustomCacheInterceptor)
@Get("/myprofile")
async myProfile(@Req() request: AuthRequest) {
try {
return (
await this.userService.findUsersByFilter(
{ email: request.user.email },
true,
)
)[0];
} catch (error) {
console.error(error);
throw new ServiceUnavailableException(error);
}
}
@UseGuards(new RolesAuthGuard(["investor"]))
@UseInterceptors(CustomCacheInterceptor)
@Get("instrument/:instrumentId/balance")
async getBalance(
@Req() request: AuthRequest,
@Param("instrumentId") instrumentId: string,
) {
try {
const investor = await this.userService.findUserByProperty({
email: request.user.email,
});
return await this.userService.getInvestorBalanceByInstrument({
investor,
instrumentId,
});
} catch (error) {
console.error(error);
if (error.status === 400) {
throw new BadRequestException(error);
}
if (error.status === 401) {
throw new UnauthorizedException(error);
}
throw new ServiceUnavailableException(error);
}
}
@UseGuards(new RolesAuthGuard(["admin", "dealer"]))
@Get("/:id")
async findOne(@Req() request: AuthRequest, @Param("id") id: string) {
try {
if (request.user.role === EndUserRoles.dealer) {
const isAllowed = await this.userService.isDealerAllowed({
investorId: id,
dealerEmail: request.user.email,
});
if (!isAllowed) {
throw new UnauthorizedException(
`Dealer with email ${request.user.email} is unauthorized for this investor`,
);
}
}
return await this.userService.findOne(id, true);
} catch (error) {
console.error(error);
throw new ServiceUnavailableException(error);
}
}
@UseGuards(new RolesAuthGuard(["admin", "dealer"]))
@UseInterceptors(CustomCacheInterceptor)
@Get("/:investorId/orderbook")
async findOneWithOrderBook(
@Req() request: AuthRequest,
@Param("investorId") investorId: string,
@Query() filterOrderDto: FilterOrderDto,
) {
try {
if (request.user.role === EndUserRoles.dealer) {
const isAllowed = await this.userService.isDealerAllowed({
investorId,
dealerEmail: request.user.email,
});
if (!isAllowed) {
throw new UnauthorizedException(
`Dealer with email ${request.user.email} is unauthorized for this investor`,
);
}
}
return await this.userOrderbookService.getInvestorOrders({
investorId,
...filterOrderDto,
});
} catch (error) {
console.error(error);
if (error.status === 400) {
throw new BadRequestException(error);
}
if (error.status === 401) {
throw new UnauthorizedException(error);
}
throw new ServiceUnavailableException(error);
}
}
@UseInterceptors(CustomCacheInterceptor)
@UseGuards(new RolesAuthGuard(["admin", "fundAdmin"]))
@Get("/:userId/fund/:fundId")
async getFundDetailsSubscription(
@Req() request: AuthRequest,
@Param("userId") userId: string,
@Param("fundId") fundId: string,
) {
try {
if (request.user.role !== "admin") {
await this.userService.checkIfUserIsAllowedToFund(request.user, fundId);
}
return await this.userService.getFundSubscriptionDetails({
userId,
fundId,
});
} catch (error) {
console.error(error);
throw new ServiceUnavailableException(error);
}
}
@UseGuards(new RolesAuthGuard(["admin", "dealer"]))
@Put("/:id")
async update(
@Param("id") id: string,
@Req() request: AuthRequest,
@Body() updateUserDto: UpdateUserDto,
) {
try {
if (request.user.role === EndUserRoles.dealer) {
const isAllowed = await this.userService.isDealerAllowed({
investorId: id,
dealerEmail: request.user.email,
});
if (!isAllowed) {
throw new UnauthorizedException(
"Dealer is Unauthorized for this action",
);
}
}
return this.userService.update({
id,
updateUserDto,
userJwtPayload: request.user,
});
} catch (error) {
console.error(error);
throw new ServiceUnavailableException(error);
}
}
@UseGuards(new RolesAuthGuard(["admin", "dealer"]))
@Put("/:id/subscribe")
async subscribeUser(
@Param("id") id: string,
@Req() request: AuthRequest,
@Body() subscribeUserDto: SubscribeUserDto,
) {
if (request.user.role === EndUserRoles.dealer) {
const isAllowed = await this.userService.isDealerAllowed({
investorId: id,
dealerEmail: request.user.email,
fundId: subscribeUserDto.fundId,
});
if (!isAllowed) {
throw new UnauthorizedException(
"Dealer is Unauthorized for this action",
);
}
}
const updateResult = await this.userService.userSubscribeToNewFund({
userId: id,
userJwt: request.user,
...subscribeUserDto,
});
if (!updateResult) {
throw new ServiceUnavailableException("Tx didn't pass");
}
if (updateResult) {
return {
message: `User ${
subscribeUserDto.isSubscribed ? "subscribed" : "unsubscribed"
} to fund ${subscribeUserDto.fundId} successfully!`,
};
}
throw new BadRequestException(
`Incorrect Id for fund ${subscribeUserDto.fundId}`,
);
}
@UseGuards(new RolesAuthGuard(["admin"]))
@Put("/:id/assign/dealer")
async assignInvestorToNewDealer(
@Param("id") id: string,
@Body() assignNewDealerDto: AssignNewDealerDto,
) {
const user = await this.userService.findOne(id);
if (!user) {
throw new BadRequestException("User not found");
}
if (user.endUserRole !== EndUserRoles.investor) {
throw new BadRequestException(`${user.email} is not an investor`);
}
try {
return await transactionSubmitter({
signerKey: process.env.RELAYER_KEY,
contractAddress: getContractByName["InvestorRegistry"].address,
transactionName: TransactionNames.assignInvestorToNewDealer,
contractName: ContractName.InvestorRegistry,
args: [
Roles.Dealer,
encodeBytes32String(id),
encodeBytes32String(assignNewDealerDto.dealerId),
],
});
} catch (error) {
throw new ServiceUnavailableException(error);
}
}
// Creating new wallets will be supported once we depend on multiple custodial
@UseGuards(new RolesAuthGuard(["admin"]))
@Post("/:id/wallet")
async createWallet(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
@Param("id") id: string,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
@Req() request: AuthRequest,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
@Body() updateWalletDto: UpdateWalletDto,
) {
throw new BadRequestException(
"Only one wallet per user is supported until adding other external custodial and external wallets",
);
}
@UseGuards(new RolesAuthGuard(["admin", "dealer", "investor"]))
@Get(":id/wallet/")
async getWallets(@Req() request: AuthRequest, @Param("id") id: string) {
if (request.user.role === EndUserRoles.dealer) {
const isAllowed = await this.userService.isDealerAllowed({
investorId: id,
dealerEmail: request.user.email,
});
if (!isAllowed) {
throw new UnauthorizedException("Role Unauthorized for this action");
}
}
const user = await this.userService.findOne(id);
if (!user) {
throw new BadRequestException(`No user exist with id ${id}`);
}
if (request.user.role === EndUserRoles.investor) {
if (user.email !== request.user.email) {
throw new UnauthorizedException("Role Unauthorized for this action");
}
}
const wallets = await this.walletService.findByIds(user.wallets);
return wallets;
}
@UseGuards(new RolesAuthGuard(["admin", "dealer"]))
@Get(":id/wallet/:address")
async getWalletsByAddress(@Param("address") address: string) {
const wallet = await this.walletService.findByAddress(address);
if (!wallet) {
throw new BadRequestException(`No wallet found with address ${address}`);
}
return wallet;
}
@UseGuards(new RolesAuthGuard(["admin", "dealer", "investor"]))
@Put(":id/wallet/:address")
async updateWalletLabel(
@Req() request: AuthRequest,
@Param("id") id: string,
@Param("address") address: string,
@Body() updateWalletDto: UpdateWalletDto,
) {
if (request.user.role === EndUserRoles.dealer) {
const isAllowed = await this.userService.isDealerAllowed({
investorId: id,
dealerEmail: request.user.email,
});
if (!isAllowed) {
throw new UnauthorizedException("Role Unauthorized for this action");
}
}
if (
request.user.role !== EndUserRoles.dealer &&
request.user.role === "admin"
) {
const user = await this.userService.findOne(id);
const isAllowed =
user.wallets.findIndex((wallet) => wallet.address === address) !== -1;
if (!isAllowed) {
throw new UnauthorizedException("Role Unauthorized for this action");
}
}
const wallet = await this.walletService.findByAddress(address);
if (!wallet) {
throw new BadRequestException(`No wallet exist with id ${address}`);
}
const updatedWallet = await this.walletService.update(
wallet._id,
updateWalletDto,
);
if (updatedWallet.id) {
return { ...updatedWallet.toObject(), ...updateWalletDto };
}
}
@CacheTTL(1000000)
@UseInterceptors(CacheInterceptor)
@Get("register/form")
async getRegisterForm() {
try {
return await this.userCmsService.getOnboardConfigOfDealer(
DEFAULT_LIBRE_DEALER,
);
} catch (err) {
console.error(err);
if (err.status === 400) {
throw new BadRequestException(err);
}
throw new ServiceUnavailableException(err.message);
}
}
// add delete & transfer wallet once we have the smart contracts
@UseInterceptors(CustomCacheInterceptor)
@UseGuards(new RolesAuthGuard(["admin", "dealer"]))
@Get("/dealer/onboard-config")
async getOnboardConfig(
@Req() request: AuthRequest,
@Query() dealerConfigDto: DealerConfigDto,
) {
try {
if (request.user.role === "admin" && !dealerConfigDto) {
throw new BadRequestException("Admin should send the dealer email");
}
return await this.userCmsService.getOnboardConfigOfDealer(
request.user.role === "admin"
? dealerConfigDto.dealerEmail
: request.user.email,
);
} catch (err) {
console.error(err);
if (err.status === 400) {
throw new BadRequestException(err);
}
throw new ServiceUnavailableException(err.message);
}
}
@UseInterceptors(CustomCacheInterceptor)
@UseGuards(new RolesAuthGuard(["admin", "dealer"]))
@Get("/dealer/editable-form")
async getEditableForm(
@Req() request: AuthRequest,
@Query() dealerConfigDto: DealerConfigDto,
) {
try {
if (request.user.role === "admin" && !dealerConfigDto) {
throw new BadRequestException("Admin should send the dealer email");
}
return await this.userCmsService.getEditableFormOfDealer(
request.user.role === "admin"
? dealerConfigDto.dealerEmail
: request.user.email,
);
} catch (err) {
console.error(err);
if (err.status === 400) {
throw new BadRequestException(err);
}
throw new ServiceUnavailableException(err.message);
}
}
@UseInterceptors(CustomCacheInterceptor)
@UseGuards(AuthGuard("jwt"))
@Get("/dealer/onchain-fields")
async getOnchainFieldMapping() {
try {
return await this.userCmsService.getOnboardOnchainFields();
} catch (err) {
console.error(err);
throw new ServiceUnavailableException(err.message);
}
}
@UseGuards(new RolesAuthGuard(["admin", "dealer"]))
@Put("/dealer/editable-form")
async updateOnboardEditableFields(
@Req() request: AuthRequest,
@Body() onboardEditableForm: OnboardEditableFormDto,
) {
try {
return await this.userCmsService.updateOnboardEditableFields(
request.user.email,
onboardEditableForm.onboardEditableFields,
onboardEditableForm.id,
);
} catch (err) {
console.error(err);
throw new ServiceUnavailableException(err.message);
}
}
}