Merge Staging in Preprod
This commit is contained in:
commit
8716964d2e
@ -7,6 +7,8 @@ RUN npm install -D prisma@4.11.0
|
||||
COPY package.json ./
|
||||
|
||||
RUN apk update && apk add openssh-client git
|
||||
# ENV PUPPETEER_CACHE_DIR=~/leCoffre/.cache/puppeteer
|
||||
# ENV PUPPETEER_SKIP_DOWNLOAD=false
|
||||
|
||||
COPY id_rsa /root/.ssh/id_rsa
|
||||
RUN chmod 600 ~/.ssh/id_rsa
|
||||
@ -22,6 +24,8 @@ WORKDIR leCoffre
|
||||
|
||||
COPY --from=deps leCoffre/node_modules ./node_modules
|
||||
COPY --from=deps leCoffre/package.json package.json
|
||||
#COPY --from=deps leCoffre/.cache ./.cache
|
||||
|
||||
COPY tsconfig.json tsconfig.json
|
||||
COPY src src
|
||||
|
||||
@ -39,8 +43,9 @@ COPY --from=builder --chown=lecoffreuser leCoffre/node_modules ./node_modules
|
||||
COPY --from=builder --chown=lecoffreuser leCoffre/dist dist
|
||||
COPY --from=builder --chown=lecoffreuser leCoffre/package.json ./package.json
|
||||
COPY --from=builder --chown=lecoffreuser leCoffre/src/common/databases ./src/common/databases
|
||||
#COPY --from=builder --chown=lecoffreuser leCoffre/.cache ./.cache
|
||||
|
||||
USER lecoffreuser
|
||||
|
||||
CMD ["npm", "run", "api:start"]
|
||||
CMD ["npm", "run", "start"]
|
||||
EXPOSE 3001
|
@ -5,7 +5,7 @@ scwSecretKey: AgChoEnPitXp4Ny/rVMEcevaWKNVpyj2cJYAcq+yFqKwVwnLB+ffDvwqz9XBHu+6d4
|
||||
lecoffreBack:
|
||||
serviceAccountName: lecoffre-back-sa
|
||||
envSecrets: stg-env
|
||||
command: "'sh', '-c', 'export $(xargs </etc/env/.env) && npm run api:start'"
|
||||
command: "'sh', '-c', 'export $(xargs </etc/env/.env) && npm run start'"
|
||||
imagePullSecrets:
|
||||
- name: docker-pull-secret
|
||||
image:
|
||||
|
@ -53,7 +53,7 @@
|
||||
"express": "^4.18.2",
|
||||
"fp-ts": "^2.16.1",
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
"le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.84",
|
||||
"le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.86",
|
||||
"module-alias": "^2.2.2",
|
||||
"monocle-ts": "^2.3.13",
|
||||
"multer": "^1.4.5-lts.1",
|
||||
|
@ -8,6 +8,7 @@ import { validateOrReject } from "class-validator";
|
||||
import authHandler from "@App/middlewares/AuthHandler";
|
||||
import ruleHandler from "@App/middlewares/RulesHandler";
|
||||
import roleHandler from "@App/middlewares/RolesHandler";
|
||||
import { Prisma } from "@prisma/client";
|
||||
|
||||
@Controller()
|
||||
@Service()
|
||||
@ -28,6 +29,12 @@ export default class CustomersController extends ApiController {
|
||||
query = JSON.parse(req.query["q"] as string);
|
||||
}
|
||||
|
||||
const officeId: string = req.body.user.office_Id;
|
||||
if(query.where?.office_folders?.some?.office_uid) delete query.where.office_folders.some.office_uid;
|
||||
if(query.where?.office_folders?.some?.office?.uid) delete query.where?.office_folders?.some?.office?.uid;
|
||||
const customerWhereInput: Prisma.CustomersWhereInput = { ...query.where, office_folders: { some: { office_uid: officeId } }};
|
||||
query.where = customerWhereInput;
|
||||
|
||||
//call service to get prisma entity
|
||||
const customersEntities = await this.customersService.get(query);
|
||||
|
||||
|
@ -10,11 +10,12 @@ import authHandler from "@App/middlewares/AuthHandler";
|
||||
import ruleHandler from "@App/middlewares/RulesHandler";
|
||||
import officeRoleHandler from "@App/middlewares/OfficeMembershipHandlers/OfficeRoleHandler";
|
||||
import roleHandler from "@App/middlewares/RolesHandler";
|
||||
import RulesService from "@Services/admin/RulesService/RulesService";
|
||||
|
||||
@Controller()
|
||||
@Service()
|
||||
export default class OfficeRolesController extends ApiController {
|
||||
constructor(private officeRolesService: OfficeRolesService) {
|
||||
constructor(private officeRolesService: OfficeRolesService, private rulesService: RulesService) {
|
||||
super();
|
||||
}
|
||||
|
||||
@ -30,7 +31,7 @@ export default class OfficeRolesController extends ApiController {
|
||||
query = JSON.parse(req.query["q"] as string);
|
||||
}
|
||||
|
||||
if(req.query["search"] && typeof req.query["search"] === "string") {
|
||||
if (req.query["search"] && typeof req.query["search"] === "string") {
|
||||
const filter = req.query["search"];
|
||||
query = {
|
||||
where: {
|
||||
@ -39,7 +40,7 @@ export default class OfficeRolesController extends ApiController {
|
||||
mode: "insensitive",
|
||||
},
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const officeId: string = req.body.user.office_Id;
|
||||
@ -108,11 +109,23 @@ export default class OfficeRolesController extends ApiController {
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.body.rules) {
|
||||
const allRules = await this.rulesService.get({
|
||||
where: {
|
||||
namespace: "notary",
|
||||
},
|
||||
});
|
||||
|
||||
req.body.rules = req.body.rules.filter((rule: any) => {
|
||||
const ruleFound = allRules.find((r) => r.uid === rule.uid && r.namespace === "notary");
|
||||
return ruleFound;
|
||||
});
|
||||
}
|
||||
//init IOfficeRole resource with request body values
|
||||
const officeRoleEntity = OfficeRole.hydrate<OfficeRole>(req.body);
|
||||
|
||||
//validate officeRole
|
||||
await validateOrReject(officeRoleEntity, { groups: ["updateOfficeRole"] });
|
||||
await validateOrReject(officeRoleEntity, { groups: ["updateOfficeRole"] });
|
||||
|
||||
//call service to get prisma entity
|
||||
const officeRoleEntityUpdated = await this.officeRolesService.update(officeRoleEntity);
|
||||
|
@ -1,79 +0,0 @@
|
||||
import { Response, Request } from "express";
|
||||
import { Controller, Get } from "@ControllerPattern/index";
|
||||
import ApiController from "@Common/system/controller-pattern/ApiController";
|
||||
import CustomersService from "@Services/customer/CustomersService/CustomersService";
|
||||
import { Service } from "typedi";
|
||||
import Customer from "le-coffre-resources/dist/Customer";
|
||||
import authHandler from "@App/middlewares/AuthHandler";
|
||||
import ruleHandler from "@App/middlewares/RulesHandler";
|
||||
|
||||
@Controller()
|
||||
@Service()
|
||||
export default class CustomersController extends ApiController {
|
||||
constructor(private customersService: CustomersService) {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Get all customers
|
||||
*/
|
||||
@Get("/api/v1/customer/customers")
|
||||
protected async get(req: Request, response: Response) {
|
||||
try {
|
||||
//get query
|
||||
let query;
|
||||
if (req.query["q"]) {
|
||||
query = JSON.parse(req.query["q"] as string);
|
||||
}
|
||||
|
||||
|
||||
//call service to get prisma entity
|
||||
const customersEntities = await this.customersService.get(query);
|
||||
|
||||
//Hydrate ressource with prisma entity
|
||||
const customers = Customer.hydrateArray<Customer>(customersEntities, { strategy: "excludeAll" });
|
||||
|
||||
//success
|
||||
this.httpSuccess(response, customers);
|
||||
} catch (error) {
|
||||
this.httpInternalError(response, error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @description Get a specific customer by uid
|
||||
*/
|
||||
@Get("/api/v1/customer/customers/:uid", [authHandler, ruleHandler])
|
||||
protected async getOneByUid(req: Request, response: Response) {
|
||||
try {
|
||||
const uid = req.params["uid"];
|
||||
if (!uid) {
|
||||
this.httpBadRequest(response, "No uid provided");
|
||||
return;
|
||||
}
|
||||
|
||||
let query;
|
||||
if (req.query["q"]) {
|
||||
query = JSON.parse(req.query["q"] as string);
|
||||
}
|
||||
|
||||
const customerEntity = await this.customersService.getByUid(uid, query);
|
||||
|
||||
if (!customerEntity) {
|
||||
this.httpNotFoundRequest(response, "customer not found");
|
||||
return;
|
||||
}
|
||||
|
||||
//Hydrate ressource with prisma entity
|
||||
const customer = Customer.hydrate<Customer>(customerEntity, { strategy: "excludeAll" });
|
||||
|
||||
//success
|
||||
this.httpSuccess(response, customer);
|
||||
} catch (error) {
|
||||
this.httpInternalError(response, error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
@ -24,13 +24,14 @@ export default class DocumentsController extends ApiController {
|
||||
protected async get(req: Request, response: Response) {
|
||||
try {
|
||||
//get query
|
||||
let query: Prisma.CustomersFindManyArgs = {};
|
||||
let query: Prisma.DocumentsFindManyArgs = {};
|
||||
if (req.query["q"]) {
|
||||
query = JSON.parse(req.query["q"] as string);
|
||||
}
|
||||
|
||||
const customerId: string = req.body.user.customerId;
|
||||
const customerWhereInput: Prisma.DocumentsWhereInput ={ depositor: { uid: customerId } };
|
||||
if(query.where?.depositor) delete query.where.depositor;
|
||||
if(query.where?.depositor_uid) delete query.where.depositor_uid;
|
||||
const customerWhereInput: Prisma.DocumentsWhereInput = { ...query.where, depositor: { uid: customerId } };
|
||||
query.where = customerWhereInput;
|
||||
|
||||
|
||||
|
@ -5,6 +5,8 @@ import OfficeFoldersService from "@Services/customer/OfficeFoldersService/Office
|
||||
import { Service } from "typedi";
|
||||
import { OfficeFolders, Prisma } from "@prisma/client";
|
||||
import { OfficeFolder } from "le-coffre-resources/dist/Customer";
|
||||
import officeFolderHandler from "@App/middlewares/CustomerHandler/FolderHandler";
|
||||
import authHandler from "@App/middlewares/AuthHandler";
|
||||
// import authHandler from "@App/middlewares/AuthHandler";
|
||||
// import ruleHandler from "@App/middlewares/RulesHandler";
|
||||
// import folderHandler from "@App/middlewares/OfficeMembershipHandlers/FolderHandler";
|
||||
@ -19,7 +21,7 @@ export default class OfficeFoldersController extends ApiController {
|
||||
/**
|
||||
* @description Get all folders
|
||||
*/
|
||||
@Get("/api/v1/customer/folders")
|
||||
@Get("/api/v1/customer/folders", [authHandler])
|
||||
protected async get(req: Request, response: Response) {
|
||||
try {
|
||||
//get query
|
||||
@ -28,37 +30,14 @@ export default class OfficeFoldersController extends ApiController {
|
||||
query = JSON.parse(req.query["q"] as string);
|
||||
}
|
||||
|
||||
|
||||
if (req.query["search"] && typeof req.query["search"] === "string") {
|
||||
const filter = req.query["search"];
|
||||
query = {
|
||||
where: {
|
||||
OR: [
|
||||
{
|
||||
name: { contains: filter, mode: "insensitive" },
|
||||
},
|
||||
{
|
||||
folder_number: { contains: filter, mode: "insensitive" },
|
||||
},
|
||||
{
|
||||
customers: {
|
||||
some: {
|
||||
contact: {
|
||||
OR: [
|
||||
{ first_name: { contains: filter, mode: "insensitive" } },
|
||||
{ last_name: { contains: filter, mode: "insensitive" } },
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
const customerId: string = req.body.user.customerId;
|
||||
if(!customerId) {
|
||||
this.httpBadRequest(response, "No customerId provided");
|
||||
return;
|
||||
}
|
||||
const officeWhereInput: Prisma.OfficesWhereInput = {};
|
||||
if (!query.where) query.where = { office: officeWhereInput };
|
||||
query.where.office = officeWhereInput;
|
||||
if(query.where?.customers) delete query.where.customers;
|
||||
const officeFolderWhereInput: Prisma.OfficeFoldersWhereInput = { ...query.where, customers: { some: { uid: customerId } }};
|
||||
query.where = officeFolderWhereInput;
|
||||
|
||||
//call service to get prisma entity
|
||||
const officeFolderEntities: OfficeFolders[] = await this.officeFoldersService.get(query);
|
||||
@ -79,7 +58,7 @@ export default class OfficeFoldersController extends ApiController {
|
||||
* @description Get a specific folder by uid
|
||||
* @returns IFolder
|
||||
*/
|
||||
@Get("/api/v1/customer/folders/:uid")
|
||||
@Get("/api/v1/customer/folders/:uid", [authHandler, officeFolderHandler])
|
||||
protected async getOneByUid(req: Request, response: Response) {
|
||||
try {
|
||||
const uid = req.params["uid"];
|
||||
@ -91,8 +70,10 @@ export default class OfficeFoldersController extends ApiController {
|
||||
let query;
|
||||
if (req.query["q"]) {
|
||||
query = JSON.parse(req.query["q"] as string);
|
||||
if(query?.customers) {
|
||||
query.customers = true;
|
||||
}
|
||||
}
|
||||
|
||||
const officeFolderEntity = await this.officeFoldersService.getByUid(uid, query);
|
||||
|
||||
if (!officeFolderEntity) {
|
||||
|
@ -35,13 +35,11 @@ export default class CustomerController extends ApiController {
|
||||
}
|
||||
try {
|
||||
const enrollment = await this.id360Service.getEnrollment(callbackToken);
|
||||
console.log("enrollment", enrollment);
|
||||
if (enrollment.status !== "OK") {
|
||||
this.httpUnauthorized(response, "Enrollment status is not OK");
|
||||
return;
|
||||
}
|
||||
const customerData = await this.id360Service.getReport(enrollment.id);
|
||||
console.log(customerData.external_methods.france_connect.results);
|
||||
const customer = await this.customerService.get({
|
||||
where: {
|
||||
contact: {
|
||||
@ -55,7 +53,6 @@ export default class CustomerController extends ApiController {
|
||||
contact: true,
|
||||
}
|
||||
});
|
||||
console.log(customer);
|
||||
// const contact = await this.customerService.getByEmail(
|
||||
// customerData.external_methods.france_connect.results.france_connect_out_userinfo[0].email,
|
||||
// );
|
||||
|
@ -50,10 +50,7 @@ export default class DocumentController extends ApiController {
|
||||
this.httpBadRequest(response, "Missing document id");
|
||||
return;
|
||||
}
|
||||
|
||||
const enrl = await this.id360Service.createEnrollment(documentId!);
|
||||
console.log(enrl)
|
||||
|
||||
await this.id360Service.createEnrollment(documentId!);
|
||||
//success
|
||||
this.httpSuccess(response);
|
||||
} catch (error) {
|
||||
|
@ -37,30 +37,7 @@ export default class UserController extends ApiController {
|
||||
const payload = await this.authService.getUserJwtPayload(user.idNot);
|
||||
const accessToken = this.authService.generateAccessToken(payload);
|
||||
const refreshToken = this.authService.generateRefreshToken(payload);
|
||||
|
||||
this.httpSuccess(response, { accessToken, refreshToken });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
this.httpInternalError(response);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@Post("/api/v1/idnot/user/login/:idnot")
|
||||
protected async login(req: Request, response: Response) {
|
||||
try {
|
||||
const id = req.params["idnot"];
|
||||
if (!id) throw new Error("idnot is required");
|
||||
|
||||
const payload = await this.authService.getUserJwtPayload(id);
|
||||
if (!payload) {
|
||||
this.httpNotFoundRequest(response);
|
||||
return;
|
||||
}
|
||||
const accessToken = this.authService.generateAccessToken(payload);
|
||||
const refreshToken = this.authService.generateRefreshToken(payload);
|
||||
|
||||
//success
|
||||
|
||||
this.httpSuccess(response, { accessToken, refreshToken });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
|
@ -7,6 +7,7 @@ import { Customer } from "le-coffre-resources/dist/Notary";
|
||||
import { validateOrReject } from "class-validator";
|
||||
import authHandler from "@App/middlewares/AuthHandler";
|
||||
import ruleHandler from "@App/middlewares/RulesHandler";
|
||||
import { Prisma } from "@prisma/client";
|
||||
|
||||
@Controller()
|
||||
@Service()
|
||||
@ -22,11 +23,17 @@ export default class CustomersController extends ApiController {
|
||||
protected async get(req: Request, response: Response) {
|
||||
try {
|
||||
//get query
|
||||
let query;
|
||||
let query: Prisma.CustomersFindManyArgs = {};
|
||||
if (req.query["q"]) {
|
||||
query = JSON.parse(req.query["q"] as string);
|
||||
}
|
||||
|
||||
const officeId: string = req.body.user.office_Id;
|
||||
if(query.where?.office_folders?.some?.office_uid) delete query.where.office_folders.some.office_uid;
|
||||
if(query.where?.office_folders?.some?.office?.uid) delete query.where?.office_folders?.some?.office?.uid;
|
||||
const customerWhereInput: Prisma.CustomersWhereInput = { ...query.where, office_folders: { some: { office_uid: officeId } }};
|
||||
query.where = customerWhereInput;
|
||||
|
||||
//call service to get prisma entity
|
||||
const customersEntities = await this.customersService.get(query);
|
||||
|
||||
|
@ -5,15 +5,35 @@ import { Service } from "typedi";
|
||||
import { OfficeFolder } from "le-coffre-resources/dist/Notary";
|
||||
import { getFolderHashes } from "@Common/optics/notary";
|
||||
import OfficeFoldersService from "@Services/notary/OfficeFoldersService/OfficeFoldersService";
|
||||
import OfficeFolderAnchorsRepository from "@Repositories/OfficeFolderAnchorsRepository";
|
||||
import SecureService from "@Services/common/SecureService/SecureService";
|
||||
import authHandler from "@App/middlewares/AuthHandler";
|
||||
import ruleHandler from "@App/middlewares/RulesHandler";
|
||||
import folderHandler from "@App/middlewares/OfficeMembershipHandlers/FolderHandler";
|
||||
import OfficeFolderAnchor from "le-coffre-resources/dist/Notary/OfficeFolderAnchor";
|
||||
|
||||
const hydrateOfficeFolderAnchor = (data: any): OfficeFolderAnchor =>
|
||||
OfficeFolderAnchor.hydrate<OfficeFolderAnchor>(
|
||||
{
|
||||
hash_sources: data.hash_sources,
|
||||
root_hash: data.root_hash,
|
||||
|
||||
blockchain: data.transactions[0].blockchain,
|
||||
status: data.transactions[0].status,
|
||||
|
||||
anchor_nb_try: data.transactions[0].anchor_nb_try,
|
||||
tx_id: data.transactions[0].tx_id?.toString() ?? undefined,
|
||||
tx_link: data.transactions[0].tx_link,
|
||||
tx_hash: data.transactions[0].tx_hash,
|
||||
|
||||
anchored_at: data.transactions[0].anchoring_timestamp,
|
||||
},
|
||||
{ strategy: "excludeAll" },
|
||||
);
|
||||
@Controller()
|
||||
@Service()
|
||||
export default class OfficeFoldersController extends ApiController {
|
||||
constructor(private secureService: SecureService, private officeFoldersService: OfficeFoldersService) {
|
||||
constructor(private secureService: SecureService, private officeFolderAnchorsRepository: OfficeFolderAnchorsRepository, private officeFoldersService: OfficeFoldersService) {
|
||||
super();
|
||||
}
|
||||
|
||||
@ -83,16 +103,30 @@ export default class OfficeFoldersController extends ApiController {
|
||||
files: true,
|
||||
},
|
||||
},
|
||||
folder_anchor: true,
|
||||
};
|
||||
|
||||
const officeFolderFound = await this.officeFoldersService.getByUid(uid, query);
|
||||
const officeFolderFound: any = await this.officeFoldersService.getByUid(uid, query);
|
||||
|
||||
if (!officeFolderFound) {
|
||||
this.httpNotFoundRequest(response, "Office folder not found");
|
||||
return;
|
||||
}
|
||||
|
||||
const officeFolderAnchorFound = OfficeFolderAnchor.hydrate<OfficeFolderAnchor>(officeFolderFound.folder_anchor, {
|
||||
strategy: "excludeAll",
|
||||
});
|
||||
|
||||
if (officeFolderAnchorFound) {
|
||||
this.httpBadRequest(response, {
|
||||
error: "Office folder already anchored",
|
||||
folder_anchor: officeFolderAnchorFound,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const officeFolder = OfficeFolder.hydrate<OfficeFolder>(officeFolderFound, { strategy: "excludeAll" });
|
||||
|
||||
const folderHashes = getFolderHashes(officeFolder);
|
||||
|
||||
if (folderHashes.length === 0) {
|
||||
@ -101,9 +135,20 @@ export default class OfficeFoldersController extends ApiController {
|
||||
}
|
||||
|
||||
const sortedHashes = [...folderHashes].sort();
|
||||
const anchor = await this.secureService.anchor(sortedHashes);
|
||||
const data = await this.secureService.anchor(sortedHashes);
|
||||
|
||||
this.httpSuccess(response, anchor);
|
||||
const officeFolderAnchor = hydrateOfficeFolderAnchor(data);
|
||||
|
||||
const newOfficeFolderAnchor = await this.officeFolderAnchorsRepository.create(
|
||||
officeFolderAnchor
|
||||
);
|
||||
|
||||
await this.officeFoldersService.update(
|
||||
uid,
|
||||
OfficeFolder.hydrate<OfficeFolder>({ uid: uid, folder_anchor: newOfficeFolderAnchor }, { strategy: "excludeAll" }),
|
||||
);
|
||||
|
||||
this.httpSuccess(response, officeFolderAnchor);
|
||||
} catch (error) {
|
||||
this.httpInternalError(response, error);
|
||||
return;
|
||||
@ -129,9 +174,10 @@ export default class OfficeFoldersController extends ApiController {
|
||||
files: true,
|
||||
},
|
||||
},
|
||||
folder_anchor: true,
|
||||
};
|
||||
|
||||
const officeFolderFound = await this.officeFoldersService.getByUid(uid, query);
|
||||
const officeFolderFound: any = await this.officeFoldersService.getByUid(uid, query);
|
||||
|
||||
if (!officeFolderFound) {
|
||||
this.httpNotFoundRequest(response, "Office folder not found");
|
||||
@ -147,9 +193,31 @@ export default class OfficeFoldersController extends ApiController {
|
||||
}
|
||||
|
||||
const sortedHashes = [...folderHashes].sort();
|
||||
const anchor = await this.secureService.verify(sortedHashes);
|
||||
const officeFolderAnchorFound = OfficeFolderAnchor.hydrate<OfficeFolderAnchor>(officeFolderFound.folder_anchor, {
|
||||
strategy: "excludeAll",
|
||||
});
|
||||
|
||||
this.httpSuccess(response, anchor);
|
||||
if (!officeFolderAnchorFound || !officeFolderAnchorFound.uid) {
|
||||
this.httpNotFoundRequest(response, {error: "Not anchored", hash_sources: sortedHashes});
|
||||
return;
|
||||
}
|
||||
|
||||
const data = await this.secureService.verify(sortedHashes);
|
||||
|
||||
if (data.errors || data.transactions.length === 0) {
|
||||
this.httpNotFoundRequest(response, {error: "Not anchored", hash_sources: sortedHashes});
|
||||
return;
|
||||
}
|
||||
|
||||
const officeFolderAnchor = hydrateOfficeFolderAnchor(data);
|
||||
|
||||
const updatedOfficeFolderAnchor = await this.officeFolderAnchorsRepository.update(
|
||||
officeFolderAnchorFound.uid,
|
||||
officeFolderAnchor
|
||||
);
|
||||
|
||||
this.httpSuccess(response, updatedOfficeFolderAnchor);
|
||||
return;
|
||||
} catch (error) {
|
||||
this.httpInternalError(response, error);
|
||||
return;
|
||||
|
@ -26,6 +26,10 @@ export default class RulesController extends ApiController {
|
||||
query = JSON.parse(req.query["q"] as string);
|
||||
}
|
||||
|
||||
query.where = {
|
||||
...query.where,
|
||||
namespace: "notary",
|
||||
};
|
||||
//call service to get prisma entity
|
||||
const rulesEntities = await this.rulesService.get(query);
|
||||
|
||||
@ -57,6 +61,11 @@ export default class RulesController extends ApiController {
|
||||
query = JSON.parse(req.query["q"] as string);
|
||||
}
|
||||
|
||||
query.where = {
|
||||
...query.where,
|
||||
namespace: "notary",
|
||||
};
|
||||
|
||||
const ruleEntity = await this.rulesService.getByUid(uid, query);
|
||||
|
||||
if (!ruleEntity) {
|
||||
|
@ -5,6 +5,7 @@ import { Service } from "typedi";
|
||||
import UserNotification from "le-coffre-resources/dist/Notary/UserNotification";
|
||||
import UserNotificationService from "@Services/common/UserNotificationService/UserNotificationService";
|
||||
import authHandler from "@App/middlewares/AuthHandler";
|
||||
import { Prisma } from "@prisma/client";
|
||||
|
||||
@Controller()
|
||||
@Service()
|
||||
@ -16,7 +17,7 @@ export default class UserNotificationController extends ApiController {
|
||||
/**
|
||||
* @description Get all customers
|
||||
*/
|
||||
@Get("/api/v1/notifications", [authHandler])
|
||||
@Get("/api/v1/notary/notifications", [authHandler])
|
||||
protected async get(req: Request, response: Response) {
|
||||
try {
|
||||
//get query
|
||||
@ -25,11 +26,13 @@ export default class UserNotificationController extends ApiController {
|
||||
query = JSON.parse(req.query["q"] as string);
|
||||
}
|
||||
|
||||
if (query.where) {
|
||||
query.where = { ...query.where, user: { uid: req.body.user.uid } };
|
||||
} else {
|
||||
query.where = { user: { uid: req.body.user.uid } };
|
||||
}
|
||||
|
||||
const userId: string = req.body.user.userId;
|
||||
if(query.where?.user_uid) delete query.where.user_uid;
|
||||
if(query.where?.user?.uid) delete query.where.user.uid;
|
||||
const notificationWhereInput: Prisma.UserNotificationsWhereInput = { ...query.where, user_uid: userId };
|
||||
query.where = notificationWhereInput;
|
||||
|
||||
query.include = { notification: true };
|
||||
//call service to get prisma entity
|
||||
const userNotificationEntities = await this.userNotificationService.get(query);
|
||||
@ -48,7 +51,7 @@ export default class UserNotificationController extends ApiController {
|
||||
/**
|
||||
* @description Modify a specific customer by uid
|
||||
*/
|
||||
@Put("/api/v1/notifications/:uid")
|
||||
@Put("/api/v1/notary/notifications/:uid", [authHandler])
|
||||
protected async put(req: Request, response: Response) {
|
||||
try {
|
||||
const uid = req.params["uid"];
|
||||
@ -64,6 +67,11 @@ export default class UserNotificationController extends ApiController {
|
||||
return;
|
||||
}
|
||||
|
||||
if(userNotificationFound.user_uid !== req.body.user.userId) {
|
||||
this.httpForbidden(response, "You are not allowed to update this user notification");
|
||||
return;
|
||||
}
|
||||
|
||||
//init IUser resource with request body values
|
||||
const userNotificationEntity = UserNotification.hydrate<UserNotification>(req.body);
|
||||
|
||||
@ -86,7 +94,7 @@ export default class UserNotificationController extends ApiController {
|
||||
/**
|
||||
* @description Get a specific customer by uid
|
||||
*/
|
||||
@Get("/api/v1/notifications/:uid")
|
||||
@Get("/api/v1/notary/notifications/:uid", [authHandler])
|
||||
protected async getOneByUid(req: Request, response: Response) {
|
||||
try {
|
||||
const uid = req.params["uid"];
|
||||
@ -108,6 +116,11 @@ export default class UserNotificationController extends ApiController {
|
||||
return;
|
||||
}
|
||||
|
||||
if(userNotificationEntity.user_uid !== req.body.userId) {
|
||||
this.httpForbidden(response, "You are allowed to get this user notification");
|
||||
return;
|
||||
}
|
||||
|
||||
//Hydrate ressource with prisma entity
|
||||
const userNotification = UserNotification.hydrate<UserNotification>(userNotificationEntity, { strategy: "excludeAll" });
|
||||
|
@ -8,6 +8,7 @@ import { validateOrReject } from "class-validator";
|
||||
import authHandler from "@App/middlewares/AuthHandler";
|
||||
import ruleHandler from "@App/middlewares/RulesHandler";
|
||||
import roleHandler from "@App/middlewares/RolesHandler";
|
||||
import { Prisma } from "@prisma/client";
|
||||
|
||||
@Controller()
|
||||
@Service()
|
||||
@ -28,6 +29,12 @@ export default class CustomersController extends ApiController {
|
||||
query = JSON.parse(req.query["q"] as string);
|
||||
}
|
||||
|
||||
const officeId: string = req.body.user.office_Id;
|
||||
if(query.where?.office_folders?.some?.office_uid) delete query.where.office_folders.some.office_uid;
|
||||
if(query.where?.office_folders?.some?.office?.uid) delete query.where?.office_folders?.some?.office?.uid;
|
||||
const customerWhereInput: Prisma.CustomersWhereInput = { ...query.where, office_folders: { some: { office_uid: officeId } }};
|
||||
query.where = customerWhereInput;
|
||||
|
||||
//call service to get prisma entity
|
||||
const customersEntities = await this.customersService.get(query);
|
||||
|
||||
|
@ -42,14 +42,12 @@ import FilesControllerCustomer from "./api/customer/FilesController";
|
||||
import DocumentsControllerCustomer from "./api/customer/DocumentsController";
|
||||
import OfficeFoldersController from "./api/customer/OfficeFoldersController";
|
||||
import OfficeFolderAnchorsController from "./api/notary/OfficeFolderAnchorsController";
|
||||
import CustomersController from "./api/customer/CustomersController";
|
||||
import AppointmentsController from "./api/super-admin/AppointmentsController";
|
||||
import VotesController from "./api/super-admin/VotesController";
|
||||
import LiveVoteController from "./api/super-admin/LiveVoteController";
|
||||
import DocumentControllerId360 from "./api/id360/DocumentController";
|
||||
import CustomerControllerId360 from "./api/id360/CustomerController";
|
||||
|
||||
import UserNotificationController from "./api/common/UserNotificationController";
|
||||
import UserNotificationController from "./api/notary/UserNotificationController";
|
||||
|
||||
|
||||
/**
|
||||
@ -105,7 +103,6 @@ export default {
|
||||
Container.get(DocumentsControllerCustomer);
|
||||
Container.get(OfficeFoldersController);
|
||||
Container.get(OfficeFolderAnchorsController);
|
||||
Container.get(CustomersController);
|
||||
Container.get(UserNotificationController);
|
||||
Container.get(DocumentControllerId360);
|
||||
Container.get(CustomerControllerId360);
|
||||
|
24
src/app/middlewares/CustomerHandler/FolderHandler.ts
Normal file
24
src/app/middlewares/CustomerHandler/FolderHandler.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import HttpCodes from "@Common/system/controller-pattern/HttpCodes";
|
||||
import OfficeFoldersService from "@Services/customer/OfficeFoldersService/OfficeFoldersService";
|
||||
import { NextFunction, Request, Response } from "express";
|
||||
import Container from "typedi";
|
||||
|
||||
export default async function officeFolderHandler(req: Request, response: Response, next: NextFunction) {
|
||||
const customerId = req.body.user.customerId;
|
||||
const uid = req.path && req.path.split("/")[5];
|
||||
|
||||
if (uid) {
|
||||
const officeFolderService = Container.get(OfficeFoldersService);
|
||||
const officeFolder = await officeFolderService.getByUidWithCustomers(uid);
|
||||
if (!officeFolder) {
|
||||
response.status(HttpCodes.NOT_FOUND).send("Folder not found");
|
||||
return;
|
||||
}
|
||||
if (!officeFolder.customers.find((customer) => customer.uid == customerId)) {
|
||||
response.status(HttpCodes.UNAUTHORIZED).send("Not authorized with this depositor");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
next();
|
||||
}
|
@ -45,12 +45,12 @@ export default async function documentHandler(req: Request, response: Response,
|
||||
const document = await documentService.getByUidWithOffice(uid!);
|
||||
|
||||
if (!document) {
|
||||
response.sendStatus(HttpCodes.NOT_FOUND);
|
||||
response.sendStatus(HttpCodes.NOT_FOUND).send("Document not found");
|
||||
return;
|
||||
}
|
||||
|
||||
if (document.document_type.office.uid != officeId) {
|
||||
response.sendStatus(HttpCodes.UNAUTHORIZED);
|
||||
if (document.folder.office.uid != officeId) {
|
||||
response.sendStatus(HttpCodes.UNAUTHORIZED).send("Unauthorized with this office");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,2 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "rules" ADD COLUMN "namespace" VARCHAR(255) NOT NULL DEFAULT 'notary';
|
@ -299,7 +299,7 @@ model Rules {
|
||||
updated_at DateTime? @updatedAt
|
||||
role Roles[] @relation("RolesHasRules")
|
||||
office_roles OfficeRoles[] @relation("OfficeRolesHasRules")
|
||||
|
||||
namespace String @db.VarChar(255) @default("notary")
|
||||
@@map("rules")
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,10 +1,11 @@
|
||||
import DocumentsService from "@Services/super-admin/DocumentsService/DocumentsService";
|
||||
import { Documents } from "@prisma/client";
|
||||
import { Documents, OfficeFolders } from "@prisma/client";
|
||||
import User, { Document, OfficeFolder, Vote } from "le-coffre-resources/dist/SuperAdmin";
|
||||
import { Service } from "typedi";
|
||||
import NotificationsService from "@Services/common/NotificationsService/NotificationsService";
|
||||
import UsersService from "@Services/super-admin/UsersService/UsersService";
|
||||
import OfficeFoldersService from "@Services/super-admin/OfficeFoldersService/OfficeFoldersService";
|
||||
import { BackendVariables } from "@Common/config/variables/Variables";
|
||||
|
||||
@Service()
|
||||
export default class NotificationBuilder {
|
||||
@ -13,6 +14,7 @@ export default class NotificationBuilder {
|
||||
private documentsService: DocumentsService,
|
||||
private usersService: UsersService,
|
||||
private foldersService: OfficeFoldersService,
|
||||
private backendVariables: BackendVariables
|
||||
) {}
|
||||
|
||||
public async sendDocumentDepositedNotification(documentEntity: Documents) {
|
||||
@ -32,33 +34,33 @@ export default class NotificationBuilder {
|
||||
" " +
|
||||
document.depositor?.contact?.last_name +
|
||||
" vous a envoyé un document à valider",
|
||||
redirection_url: "",
|
||||
redirection_url: `${this.backendVariables.APP_HOST}/folders/${document.folder?.uid}/documents/${document.uid}`,
|
||||
created_at: new Date(),
|
||||
updated_at: new Date(),
|
||||
user: document.folder!.stakeholders || [],
|
||||
});
|
||||
}
|
||||
|
||||
public async sendDocumentAnchoredNotification(documentEntity: Documents) {
|
||||
const documentPrisma = await this.documentsService.getByUid(documentEntity.uid, {
|
||||
depositor: { include: { contact: true } },
|
||||
folder: { include: { folder_anchor: true, office: true, stakeholders: true } },
|
||||
});
|
||||
if (!documentPrisma) throw new Error("Document not found");
|
||||
const document = Document.hydrate<Document>(documentPrisma);
|
||||
if (document.folder?.folder_anchor?.status !== "VERIFIED_ON_CHAIN") return;
|
||||
public async sendFolderAnchoredNotification(folderEntity: OfficeFolders) {
|
||||
if(!folderEntity.uid) return;
|
||||
const officeFolderPrisma = await this.foldersService.getByUid(folderEntity.uid,
|
||||
{ folder_anchor: true, office: true, stakeholders: true }
|
||||
);
|
||||
if (!officeFolderPrisma) throw new Error("Folder not found");
|
||||
const folder = OfficeFolder.hydrate<OfficeFolder>(officeFolderPrisma);
|
||||
if (folder.folder_anchor?.status !== "VERIFIED_ON_CHAIN") return;
|
||||
|
||||
this.notificationsService.create({
|
||||
message:
|
||||
"Le dossier " +
|
||||
document.folder?.folder_number +
|
||||
folder.folder_number +
|
||||
" - " +
|
||||
document.folder?.name +
|
||||
folder.name +
|
||||
" a été certifié. Vous pouvez désormais télécharger le certificat de dépôt pour le mettre dans la GED de votre logiciel de rédaction d'acte.",
|
||||
redirection_url: "",
|
||||
redirection_url: `${this.backendVariables.APP_HOST}/folders/${folder?.uid}`,
|
||||
created_at: new Date(),
|
||||
updated_at: new Date(),
|
||||
user: document.folder!.stakeholders || [],
|
||||
user: folder.stakeholders || [],
|
||||
});
|
||||
}
|
||||
|
||||
@ -80,7 +82,7 @@ export default class NotificationBuilder {
|
||||
|
||||
this.notificationsService.create({
|
||||
message: message,
|
||||
redirection_url: "",
|
||||
redirection_url: `${this.backendVariables.APP_HOST}/users/${vote.appointment.targeted_user.uid}`,
|
||||
created_at: new Date(),
|
||||
updated_at: new Date(),
|
||||
user: superAdminList || [],
|
||||
@ -131,7 +133,7 @@ export default class NotificationBuilder {
|
||||
" avant le " +
|
||||
formattedDate +
|
||||
" (date limite d'expiration des documents).",
|
||||
redirection_url: "",
|
||||
redirection_url: `${this.backendVariables.APP_HOST}/folders/${folder.uid}`,
|
||||
created_at: new Date(),
|
||||
updated_at: new Date(),
|
||||
user: folder.stakeholders || [],
|
||||
|
68
src/common/repositories/OfficeFolderAnchorsRepository.ts
Normal file
68
src/common/repositories/OfficeFolderAnchorsRepository.ts
Normal file
@ -0,0 +1,68 @@
|
||||
import Database from "@Common/databases/database";
|
||||
import BaseRepository from "@Repositories/BaseRepository";
|
||||
import { Service } from "typedi";
|
||||
import { OfficeFolderAnchors, Prisma } from "@prisma/client";
|
||||
import { OfficeFolderAnchor } from "le-coffre-resources/dist/SuperAdmin";
|
||||
|
||||
@Service()
|
||||
export default class OfficeFolderAnchorsRepository extends BaseRepository {
|
||||
constructor(private database: Database) {
|
||||
super();
|
||||
}
|
||||
protected get model() {
|
||||
return this.database.getClient().officeFolderAnchors;
|
||||
}
|
||||
protected get instanceDb() {
|
||||
return this.database.getClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* @description : Create new office folder anchor
|
||||
*/
|
||||
public async create(officeFolderAnchor: OfficeFolderAnchor): Promise<OfficeFolderAnchors> {
|
||||
const createArgs: Prisma.OfficeFolderAnchorsCreateArgs = {
|
||||
data: {
|
||||
hash_sources: officeFolderAnchor.hash_sources,
|
||||
root_hash: officeFolderAnchor.root_hash!,
|
||||
|
||||
blockchain: officeFolderAnchor.blockchain as OfficeFolderAnchors["blockchain"],
|
||||
status: officeFolderAnchor.status as OfficeFolderAnchors["status"],
|
||||
|
||||
anchor_nb_try: officeFolderAnchor.anchor_nb_try,
|
||||
tx_id: officeFolderAnchor.tx_id,
|
||||
tx_link: officeFolderAnchor.tx_link,
|
||||
tx_hash: officeFolderAnchor.tx_hash,
|
||||
|
||||
anchored_at: officeFolderAnchor.anchored_at,
|
||||
},
|
||||
};
|
||||
|
||||
return this.model.create({ ...createArgs });
|
||||
}
|
||||
|
||||
/**
|
||||
* @description : Update data of an office folder anchor
|
||||
*/
|
||||
public async update(officeFolderAnchorUid: string, officeFolderAnchor: OfficeFolderAnchor): Promise<OfficeFolderAnchors> {
|
||||
const updateArgs: Prisma.OfficeFolderAnchorsUpdateArgs = {
|
||||
where: {
|
||||
uid: officeFolderAnchorUid,
|
||||
},
|
||||
data: {
|
||||
blockchain: officeFolderAnchor.blockchain as OfficeFolderAnchors["blockchain"],
|
||||
status: officeFolderAnchor.status as OfficeFolderAnchors["status"],
|
||||
|
||||
anchor_nb_try: officeFolderAnchor.anchor_nb_try,
|
||||
tx_id: officeFolderAnchor.tx_id,
|
||||
tx_link: officeFolderAnchor.tx_link,
|
||||
tx_hash: officeFolderAnchor.tx_hash,
|
||||
|
||||
anchored_at: officeFolderAnchor.anchored_at,
|
||||
},
|
||||
};
|
||||
|
||||
return this.model.update({
|
||||
...updateArgs,
|
||||
});
|
||||
}
|
||||
}
|
@ -84,6 +84,7 @@ export default class OfficeFoldersRepository extends BaseRepository {
|
||||
uid: document.uid!,
|
||||
})),
|
||||
},
|
||||
folder_anchor_uid: officeFolder.folder_anchor?.uid,
|
||||
},
|
||||
};
|
||||
|
||||
@ -93,6 +94,7 @@ export default class OfficeFoldersRepository extends BaseRepository {
|
||||
stakeholders: true,
|
||||
customers: true,
|
||||
documents: true,
|
||||
folder_anchor: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
@ -109,6 +111,20 @@ export default class OfficeFoldersRepository extends BaseRepository {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description : Find one office folder
|
||||
*/
|
||||
public async findOneByUidWithCustomers(uid: string) {
|
||||
return this.model.findUnique({
|
||||
where: {
|
||||
uid: uid,
|
||||
},
|
||||
include: {
|
||||
customers: true,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description : Find one office folder
|
||||
*/
|
||||
|
@ -31,7 +31,8 @@ export default class RulesRepository extends BaseRepository {
|
||||
const createArgs: Prisma.RulesCreateArgs = {
|
||||
data: {
|
||||
name: rule.name,
|
||||
label: rule.label
|
||||
label: rule.label,
|
||||
namespace: rule.namespace,
|
||||
},
|
||||
};
|
||||
|
||||
@ -48,7 +49,7 @@ export default class RulesRepository extends BaseRepository {
|
||||
},
|
||||
data: {
|
||||
name: rule.name,
|
||||
label: rule.label
|
||||
label: rule.label,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -40,6 +40,10 @@ export default abstract class BaseController {
|
||||
return this.httpResponse(response, HttpCodes.NOT_IMPLEMENTED, responseData);
|
||||
}
|
||||
|
||||
protected httpForbidden(response: Response, responseData: IResponseData = "Forbidden") {
|
||||
return this.httpResponse(response, HttpCodes.FORBIDDEN, responseData);
|
||||
}
|
||||
|
||||
protected httpResponse(response: Response, httpCode: HttpCodes, responseData: IResponseData = {}) {
|
||||
if (responseData instanceof Error) {
|
||||
throw responseData;
|
||||
|
@ -8,5 +8,6 @@ enum HttpCodes {
|
||||
NOT_IMPLEMENTED = 501,
|
||||
NOT_FOUND = 404,
|
||||
UNAUTHORIZED = 401,
|
||||
FORBIDDEN = 403,
|
||||
}
|
||||
export default HttpCodes;
|
||||
|
@ -53,7 +53,7 @@ export default class AnchoringProofService extends BaseService {
|
||||
<text fill="black" xml:space="preserve" style="white-space: pre" font-family="Inter" font-size="12" letter-spacing="0.5px"><tspan x="333" y="187.364">[[ANCHORING_TIME]]</tspan></text>
|
||||
<text fill="black" xml:space="preserve" style="white-space: pre" font-family="Inter" font-size="21" font-weight="600" letter-spacing="0em"><tspan x="258" y="163.136">Certificat de dépôt international</tspan></text>
|
||||
<text fill="#320756" xml:space="preserve" style="white-space: pre" font-family="Inter" font-size="11" font-weight="600" letter-spacing="0.5px"><tspan x="119" y="262">Hash :</tspan></text>
|
||||
<text fill="black" xml:space="preserve" style="white-space: pre" font-family="Inter" font-size="11" letter-spacing="0.5px"><tspan x="267" y="261.5">b834ce9229ee2c2283c837685772a473</tspan></text>
|
||||
<text fill="black" xml:space="preserve" style="white-space: pre" font-family="Inter" font-size="11" letter-spacing="0.5px"><tspan x="267" y="261.5">[[ROOT_HASH]]</tspan></text>
|
||||
<path d="M119 290H723" stroke="#E7E7E7"/>
|
||||
<text fill="#320756" xml:space="preserve" style="white-space: pre" font-family="Inter" font-size="14" font-weight="600" letter-spacing="0.5px"><tspan x="119" y="327.091">Déposant(s)</tspan></text>
|
||||
<text fill="#320756" xml:space="preserve" style="white-space: pre" font-family="Inter" font-size="11" font-weight="600" letter-spacing="0.5px"><tspan x="119" y="356">Auteur :</tspan></text>
|
||||
@ -62,7 +62,7 @@ export default class AnchoringProofService extends BaseService {
|
||||
<text fill="black" xml:space="preserve" style="white-space: pre" font-family="Inter" font-size="11" letter-spacing="0.5px"><tspan x="267" y="377.5">Smart-Chain</tspan></text>
|
||||
<path d="M119 406H723" stroke="#E7E7E7"/>
|
||||
<text fill="#320756" xml:space="preserve" style="white-space: pre" font-family="Inter" font-size="14" font-weight="600" letter-spacing="0.5px"><tspan x="119" y="443.091">Explorateur blockchain</tspan></text>
|
||||
<text fill="black" xml:space="preserve" style="white-space: pre" font-family="Inter" font-size="11" letter-spacing="0.5px" text-decoration="underline"><tspan x="119" y="472"><a href="https://tzstats.com/opYWLHH96gbV8HPajRqmoRx3UBVbr6iXz43kuHqm8ey4LLPWqeC">https://tzstats.com/opYWLHH96gbV8HPajRqmoRx3UBVbr6iXz43kuHqm8ey4LLPWqeC</a></tspan></text>
|
||||
<text fill="black" xml:space="preserve" style="white-space: pre" font-family="Inter" font-size="11" letter-spacing="0.5px" text-decoration="underline"><tspan x="119" y="472"><a href="[[TX_LINK]]">[[TX_LINK]]</a></tspan></text>
|
||||
</g>
|
||||
</svg>
|
||||
`;
|
||||
@ -73,6 +73,7 @@ export default class AnchoringProofService extends BaseService {
|
||||
public async generate(data: AnchoringProofData): Promise<Buffer> {
|
||||
const browser = await puppeteer.launch({
|
||||
headless: "new",
|
||||
executablePath: process.env['PUPPETEER_EXECUTABLE_PATH'],
|
||||
args: ["--no-sandbox", "--disable-setuid-sandbox"],
|
||||
});
|
||||
const page = await browser.newPage();
|
||||
@ -85,7 +86,10 @@ export default class AnchoringProofService extends BaseService {
|
||||
</html>
|
||||
`;
|
||||
|
||||
htmlContent = htmlContent.replace("[[ANCHORING_TIME]]", data.anchoringTime);
|
||||
htmlContent = htmlContent
|
||||
.replace("[[ROOT_HASH]]", data.rootHash)
|
||||
.replace("[[ANCHORING_TIME]]", data.anchoringTime)
|
||||
.replace(/\[\[TX_LINK\]\]/g, data.txLink);
|
||||
|
||||
await page.setContent(htmlContent);
|
||||
await page.addStyleTag({
|
||||
|
@ -1,19 +0,0 @@
|
||||
import { Contacts, Customers } from "@prisma/client";
|
||||
import BaseService from "@Services/BaseService";
|
||||
import { Service } from "typedi";
|
||||
import ContactRepository from "@Repositories/ContactRepository";
|
||||
|
||||
@Service()
|
||||
export default class DocumentsService extends BaseService {
|
||||
constructor(private contactRepository: ContactRepository) {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* @description : Get a contact by email
|
||||
* @throws {Error} If contact cannot be get by email
|
||||
*/
|
||||
public async getByEmail(email: string): Promise<(Contacts & {customers: Customers | null}) | null> {
|
||||
return this.contactRepository.findOneByEmail(email);
|
||||
}
|
||||
}
|
@ -110,7 +110,6 @@ export default class Id360Service extends BaseService {
|
||||
);
|
||||
|
||||
const resJson = (await res.json()) as EnrollmentResponse;
|
||||
console.log(resJson.id);
|
||||
return {
|
||||
franceConnectUrl: `${this.variables.DOCAPOST_BASE_URL}static/process_ui/index.html#/enrollment/${resJson.api_key}`,
|
||||
processId: resJson.id,
|
||||
@ -139,10 +138,8 @@ export default class Id360Service extends BaseService {
|
||||
);
|
||||
|
||||
const resJson = (await res.json()) as EnrollmentResponse;
|
||||
console.log(resJson);
|
||||
const route = await this.getRouteId(resJson.api_key);
|
||||
await this.selectRoute(resJson.api_key, route);
|
||||
console.log(route);
|
||||
await this.uploadDocument(resJson.api_key, documentUid);
|
||||
|
||||
return await this.getReport(resJson.id);
|
||||
|
@ -33,7 +33,7 @@ interface IRattachementData {
|
||||
name: string;
|
||||
};
|
||||
locationsUrl: string;
|
||||
}
|
||||
};
|
||||
personne: {
|
||||
numeroTelephonePro: string;
|
||||
prenom: string;
|
||||
@ -67,7 +67,7 @@ interface IOfficeData {
|
||||
};
|
||||
typeEntite: {
|
||||
name: string;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
interface IOfficeLocation {
|
||||
@ -124,7 +124,7 @@ export default class IdNotService extends BaseService {
|
||||
const token = await fetch(this.variables.IDNOT_BASE_URL + this.variables.IDNOT_CONNEXION_URL + "?" + query, { method: "POST" });
|
||||
const decodedToken = (await token.json()) as IIdNotToken;
|
||||
const decodedIdToken = jwt.decode(decodedToken.id_token) as IdNotJwtPayload;
|
||||
|
||||
|
||||
return decodedIdToken;
|
||||
}
|
||||
|
||||
@ -152,19 +152,19 @@ export default class IdNotService extends BaseService {
|
||||
public async getOfficeRole(roleName: string, officeUid: string) {
|
||||
switch (roleName) {
|
||||
case EIdnotRole.NOTAIRE_TITULAIRE:
|
||||
return (await this.officeRolesService.get({ where: {AND:[{ name: "Notaire" }, {office_uid: officeUid}]}}))[0]!;
|
||||
return (await this.officeRolesService.get({ where: { AND: [{ name: "Notaire" }, { office_uid: officeUid }] } }))[0]!;
|
||||
case EIdnotRole.NOTAIRE_ASSOCIE:
|
||||
return (await this.officeRolesService.get({ where: {AND:[{ name: "Notaire" }, {office_uid: officeUid}]}}))[0]!;
|
||||
return (await this.officeRolesService.get({ where: { AND: [{ name: "Notaire" }, { office_uid: officeUid }] } }))[0]!;
|
||||
case EIdnotRole.NOTAIRE_SALARIE:
|
||||
return (await this.officeRolesService.get({ where: {AND:[{ name: "Notaire" }, {office_uid: officeUid}]}}))[0]!;
|
||||
return (await this.officeRolesService.get({ where: { AND: [{ name: "Notaire" }, { office_uid: officeUid }] } }))[0]!;
|
||||
case EIdnotRole.COLLABORATEUR:
|
||||
return (await this.officeRolesService.get({ where: {AND:[{ name: "Collaborateur" }, {office_uid: officeUid}]}}))[0]!;
|
||||
return (await this.officeRolesService.get({ where: { AND: [{ name: "Collaborateur" }, { office_uid: officeUid }] } }))[0]!;
|
||||
case EIdnotRole.SUPPLEANT:
|
||||
return (await this.officeRolesService.get({ where: {AND:[{ name: "Collaborateur" }, {office_uid: officeUid}]}}))[0]!;
|
||||
return (await this.officeRolesService.get({ where: { AND: [{ name: "Collaborateur" }, { office_uid: officeUid }] } }))[0]!;
|
||||
case EIdnotRole.ADMINISTRATEUR:
|
||||
return (await this.officeRolesService.get({ where: {AND:[{ name: "Collaborateur" }, {office_uid: officeUid}]}}))[0]!;
|
||||
return (await this.officeRolesService.get({ where: { AND: [{ name: "Collaborateur" }, { office_uid: officeUid }] } }))[0]!;
|
||||
case EIdnotRole.CURATEUR:
|
||||
return (await this.officeRolesService.get({ where: {AND:[{ name: "Collaborateur" }, {office_uid: officeUid}]}}))[0]!;
|
||||
return (await this.officeRolesService.get({ where: { AND: [{ name: "Collaborateur" }, { office_uid: officeUid }] } }))[0]!;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
@ -193,39 +193,37 @@ export default class IdNotService extends BaseService {
|
||||
const searchParams = new URLSearchParams({
|
||||
key: this.variables.IDNOT_API_KEY,
|
||||
});
|
||||
let userData = await (await fetch(
|
||||
`${this.variables.IDNOT_API_BASE_URL}/api/pp/v2/rattachements/${user.idNot}_${user.office_membership!.idNot}?` +
|
||||
searchParams,
|
||||
{
|
||||
method: "GET",
|
||||
},
|
||||
)).json() as IRattachementData;
|
||||
|
||||
if (!userData.statutDuRattachement) {
|
||||
const rattachements = await (await fetch(
|
||||
`${this.variables.IDNOT_API_BASE_URL}/api/pp/v2/personnes/${user.idNot}/rattachements?` +
|
||||
let userData = (await (
|
||||
await fetch(
|
||||
`${this.variables.IDNOT_API_BASE_URL}/api/pp/v2/rattachements/${user.idNot}_${user.office_membership!.idNot}?` +
|
||||
searchParams,
|
||||
{
|
||||
method: "GET",
|
||||
},
|
||||
)).json() as any;
|
||||
)
|
||||
).json()) as IRattachementData;
|
||||
|
||||
if (!userData.statutDuRattachement) {
|
||||
const rattachements = (await (
|
||||
await fetch(`${this.variables.IDNOT_API_BASE_URL}/api/pp/v2/personnes/${user.idNot}/rattachements?` + searchParams, {
|
||||
method: "GET",
|
||||
})
|
||||
).json()) as any;
|
||||
if (rattachements.totalResultCount === 0) {
|
||||
await this.userService.updateCheckedAt(user.uid!);
|
||||
//await this.userService.delete(user.uid!);
|
||||
return;
|
||||
}
|
||||
const rattachementsResults = rattachements.result as IRattachementData[];
|
||||
if(!rattachementsResults) return;
|
||||
if (!rattachementsResults) return;
|
||||
rattachementsResults.forEach(async (rattachement) => {
|
||||
if (rattachement.statutDuRattachement) {
|
||||
const officeData = await (await fetch(
|
||||
`${this.variables.IDNOT_API_BASE_URL + rattachement.entiteUrl}?` +
|
||||
searchParams,
|
||||
{
|
||||
const officeData = (await (
|
||||
await fetch(`${this.variables.IDNOT_API_BASE_URL + rattachement.entiteUrl}?` + searchParams, {
|
||||
method: "GET",
|
||||
},
|
||||
)).json() as IOfficeData;
|
||||
if(officeData.typeEntite.name === "office") {
|
||||
})
|
||||
).json()) as IOfficeData;
|
||||
if (officeData.typeEntite.name === "office") {
|
||||
userData = rattachement;
|
||||
}
|
||||
}
|
||||
@ -236,7 +234,7 @@ export default class IdNotService extends BaseService {
|
||||
|
||||
if (user.office_membership!.idNot !== userData.entite.ou) {
|
||||
updates++;
|
||||
let officeData = (await this.officeService.get({ where: { idNot:userData.entite.ou } }))[0];
|
||||
let officeData = (await this.officeService.get({ where: { idNot: userData.entite.ou } }))[0];
|
||||
if (!officeData) {
|
||||
const officeLocationData = (await (
|
||||
await fetch(`${this.variables.IDNOT_API_BASE_URL + userData.entite.locationsUrl}?` + searchParams, { method: "GET" })
|
||||
@ -248,7 +246,7 @@ export default class IdNotService extends BaseService {
|
||||
office_status: this.getOfficeStatus(userData.entite.statutEntite.name),
|
||||
address: {
|
||||
address: officeLocationData.result[0]!.adrGeo4,
|
||||
city: officeLocationData.result[0]!.adrGeoVille.split(" ")[0] ?? officeLocationData.result[0]!.adrGeoVille,
|
||||
city: officeLocationData.result[0]!.adrGeoVille.split(" ")[0] ?? officeLocationData.result[0]!.adrGeoVille,
|
||||
zip_code: Number(officeLocationData.result[0]!.adrGeoCodePostal),
|
||||
created_at: null,
|
||||
updated_at: null,
|
||||
@ -279,13 +277,9 @@ export default class IdNotService extends BaseService {
|
||||
const searchParams = new URLSearchParams({
|
||||
key: this.variables.IDNOT_API_KEY,
|
||||
});
|
||||
const officeRawData = await fetch(
|
||||
`${this.variables.IDNOT_API_BASE_URL}/api/pp/v2/entities/${office.idNot}?` +
|
||||
searchParams,
|
||||
{
|
||||
method: "GET",
|
||||
},
|
||||
);
|
||||
const officeRawData = await fetch(`${this.variables.IDNOT_API_BASE_URL}/api/pp/v2/entities/${office.idNot}?` + searchParams, {
|
||||
method: "GET",
|
||||
});
|
||||
if (officeRawData.status === 404) {
|
||||
await this.officeService.updateCheckedAt(office.uid!);
|
||||
//await this.officeService.delete(office.uid!);
|
||||
@ -293,15 +287,15 @@ export default class IdNotService extends BaseService {
|
||||
}
|
||||
const officeData = (await officeRawData.json()) as IOfficeData;
|
||||
let updates = 0;
|
||||
if(office.name !== officeData.denominationSociale) {
|
||||
if (office.name !== officeData.denominationSociale) {
|
||||
updates++;
|
||||
office.name = officeData.denominationSociale;
|
||||
}
|
||||
if(office.office_status !== this.getOfficeStatus(officeData.statutEntite.name)) {
|
||||
if (office.office_status !== this.getOfficeStatus(officeData.statutEntite.name)) {
|
||||
updates++;
|
||||
office.office_status = this.getOfficeStatus(officeData.statutEntite.name);
|
||||
}
|
||||
if(updates != 0) await this.officeService.update(office.uid!, office);
|
||||
if (updates != 0) await this.officeService.update(office.uid!, office);
|
||||
await this.officeService.updateCheckedAt(office.uid!);
|
||||
}
|
||||
|
||||
@ -318,14 +312,15 @@ export default class IdNotService extends BaseService {
|
||||
})
|
||||
).json()) as IRattachementData;
|
||||
|
||||
|
||||
if(!userData.statutDuRattachement || userData.entite.typeEntite.name !== "office") {
|
||||
if (!userData.statutDuRattachement || userData.entite.typeEntite.name !== "office") {
|
||||
return null;
|
||||
}
|
||||
|
||||
const officeLocationData = (await (
|
||||
await fetch(`${this.variables.IDNOT_API_BASE_URL + userData.entite.locationsUrl}?` + searchParams, { method: "GET" })
|
||||
).json()) as IOfficeLocation;
|
||||
|
||||
const office = await this.officeService.get({ where: { idNot: decodedToken.entity_idn } });
|
||||
|
||||
// if(officeLocationData.result[0]!.adrGeoCodePostal.slice(0,2) !== "35") {
|
||||
// return null;
|
||||
@ -342,7 +337,7 @@ export default class IdNotService extends BaseService {
|
||||
office_status: this.getOfficeStatus(userData.entite.statutEntite.name),
|
||||
address: {
|
||||
address: officeLocationData.result[0]!.adrGeo4,
|
||||
city: officeLocationData.result[0]!.adrGeoVille.split(" ")[0] ?? officeLocationData.result[0]!.adrGeoVille, //officeLocationData.result[0]!.adrPostaleVille,
|
||||
city: officeLocationData.result[0]!.adrGeoVille.split(" ")[0] ?? officeLocationData.result[0]!.adrGeoVille, //officeLocationData.result[0]!.adrPostaleVille,
|
||||
zip_code: Number(officeLocationData.result[0]!.adrGeoCodePostal),
|
||||
created_at: null,
|
||||
updated_at: null,
|
||||
@ -362,34 +357,40 @@ export default class IdNotService extends BaseService {
|
||||
updated_at: null,
|
||||
},
|
||||
};
|
||||
|
||||
let userHydrated = User.hydrate<User>(userToAdd);
|
||||
const user = await this.userService.create(userHydrated);
|
||||
const userOffice = await this.officeService.getByUid(user.office_uid);
|
||||
userHydrated = User.hydrate<User>(user);
|
||||
const userOfficeHydrated = Office.hydrate<Office>(userOffice!);
|
||||
|
||||
const officeRoles = await this.officeRolesService.get({ where: { office: { idNot: "0000" }}, include: { office: true, rules: true } });
|
||||
const documentTypes = await this.documentTypesService.get({ where: { office: { idNot: "0000" }}, include: { office: true } });
|
||||
const deedTypes = await this.deedTypesService.get({ where:{ office: { idNot: "0000" }}, include: { office: true, document_types: true } });
|
||||
|
||||
const officeRolesHydrated = OfficeRole.hydrateArray<OfficeRole>(officeRoles);
|
||||
const documentTypesHydrated = DocumentType.hydrateArray<DocumentType>(documentTypes);
|
||||
const deedTypesHydrated = DeedType.hydrateArray<DeedType>(deedTypes);
|
||||
|
||||
officeRolesHydrated.forEach(async (officeRole) => {
|
||||
officeRole.office.uid = user.office_uid;
|
||||
await this.officeRolesService.create(officeRole);
|
||||
});
|
||||
documentTypesHydrated.forEach(async (documentType) => {
|
||||
documentType.office!.uid = user.office_uid;
|
||||
await this.documentTypesService.create(documentType);
|
||||
});
|
||||
deedTypesHydrated.forEach(async (deedType) => {
|
||||
deedType.office!.uid = user.office_uid;
|
||||
await this.deedTypesService.create(deedType);
|
||||
});
|
||||
|
||||
if(office.length === 0) {
|
||||
const officeRoles = await this.officeRolesService.get({
|
||||
where: { office: { idNot: "0000" } },
|
||||
include: { office: true, rules: true },
|
||||
});
|
||||
const deedTypes = await this.deedTypesService.get({
|
||||
where: { office: { idNot: "0000" } },
|
||||
include: { office: true, document_types: { include: { office: true } } },
|
||||
});
|
||||
const documentTypes = await this.documentTypesService.get({
|
||||
where: { office: { idNot: "0000" } },
|
||||
include: { office: true },
|
||||
});
|
||||
|
||||
const officeRolesHydrated = OfficeRole.hydrateArray<OfficeRole>(officeRoles);
|
||||
const deedTypesHydrated = DeedType.hydrateArray<DeedType>(deedTypes);
|
||||
const documentTypesHydrated = DocumentType.hydrateArray<DocumentType>(documentTypes);
|
||||
|
||||
|
||||
await this.duplicateOfficeRoles(officeRolesHydrated, userOfficeHydrated);
|
||||
const documentTypesCreated = await this.duplicateDocumentTypes(documentTypesHydrated, userOfficeHydrated);
|
||||
await this.duplicateDeedTypes(deedTypesHydrated, documentTypesCreated, userOfficeHydrated);
|
||||
}
|
||||
|
||||
const officeRole = await this.getOfficeRole(userData.typeLien.name, user.office_uid);
|
||||
|
||||
if(officeRole) {
|
||||
if (officeRole) {
|
||||
const officeRoleHydrated = OfficeRole.hydrate<OfficeRole>(officeRole!);
|
||||
userHydrated.office_role = officeRoleHydrated;
|
||||
await this.userService.update(user.uid, userHydrated);
|
||||
@ -400,12 +401,44 @@ export default class IdNotService extends BaseService {
|
||||
return user;
|
||||
}
|
||||
|
||||
public async duplicateDocumentTypes(documentTypes: DocumentType[], office: Office): Promise<DocumentType[]> {
|
||||
let newDocumentTypes: DocumentType[] = [];
|
||||
for(const documentType of documentTypes) {
|
||||
documentType.office = office;
|
||||
const documentTypeCreated = await this.documentTypesService.create(documentType);
|
||||
newDocumentTypes.push(DocumentType.hydrate<DocumentType>(documentTypeCreated));
|
||||
};
|
||||
return newDocumentTypes;
|
||||
}
|
||||
|
||||
public async duplicateDeedTypes(deedTypes: DeedType[], documentTypes: DocumentType[], office: Office) {
|
||||
for (const deedType of deedTypes) {
|
||||
let newDocumentTypes: DocumentType[] = [];
|
||||
for (const document of deedType.document_types!) {
|
||||
const newDocumentType = documentTypes.find((documentType) => documentType.name === document.name);
|
||||
if(!newDocumentType) continue;
|
||||
newDocumentTypes.push(newDocumentType!);
|
||||
};
|
||||
deedType.document_types = newDocumentTypes;
|
||||
deedType.office = office;
|
||||
await this.deedTypesService.create(deedType);
|
||||
};
|
||||
}
|
||||
|
||||
public async duplicateOfficeRoles(officeRoles: OfficeRole[], office: Office){
|
||||
for(const officeRole of officeRoles) {
|
||||
officeRole.office = office;
|
||||
await this.officeRolesService.create(officeRole);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
public async updateUsers() {
|
||||
const usersReq = await this.userService.getUsersToBeChecked();
|
||||
const users = User.hydrateArray<User>(usersReq);
|
||||
users.forEach(async (user) => {
|
||||
await this.updateUser(user.uid!);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,11 @@
|
||||
import { Customers, Prisma } from "@prisma/client";
|
||||
import CustomersRepository from "@Repositories/CustomersRepository";
|
||||
import ContactRepository from "@Repositories/ContactRepository";
|
||||
import BaseService from "@Services/BaseService";
|
||||
import { Service } from "typedi";
|
||||
|
||||
@Service()
|
||||
export default class CustomersService extends BaseService {
|
||||
constructor(private customerRepository: CustomersRepository, private contactRepository: ContactRepository) {
|
||||
constructor(private customerRepository: CustomersRepository) {
|
||||
super();
|
||||
}
|
||||
|
||||
@ -17,30 +16,4 @@ export default class CustomersService extends BaseService {
|
||||
public async get(query: Prisma.CustomersFindManyArgs): Promise<Customers[]> {
|
||||
return this.customerRepository.findMany(query);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description : Get a customer by uid
|
||||
* @throws {Error} If customer cannot be get by uid
|
||||
*/
|
||||
public async getByUid(uid: string, query?: Prisma.CustomersInclude): Promise<Customers | null> {
|
||||
return this.customerRepository.findOneByUid(uid, query);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description : Get a customer by contact uid
|
||||
* @throws {Error} If customer cannot be get by contact uid
|
||||
*/
|
||||
public async getByContact(contactUid: string): Promise<Customers | null> {
|
||||
return this.customerRepository.findOneByContact(contactUid);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description : Get a customer by contact uid
|
||||
* @throws {Error} If customer cannot be get by contact uid
|
||||
*/
|
||||
public async getByEmail(contactUid: string) {
|
||||
return this.contactRepository.findOneByEmail(contactUid);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -24,9 +24,9 @@ export default class DocumentsService extends BaseService {
|
||||
* @throws {Error} If document cannot be created
|
||||
*/
|
||||
public async create(document: Document): Promise<Documents> {
|
||||
const otherDocumentType = await this.documentTypeService.get({ where: { name: "Other" } });
|
||||
const otherDocumentType = await this.documentTypeService.get({ where: { name: "Autres documents" } });
|
||||
|
||||
if(otherDocumentType.length < 1) throw new Error("Other document type not found");
|
||||
if(otherDocumentType.length < 1) throw new Error("Autres documents document type not found");
|
||||
|
||||
document.document_type = otherDocumentType[0];
|
||||
document.document_status = "DEPOSITED";
|
||||
|
@ -26,4 +26,14 @@ export default class OfficeFoldersService extends BaseService {
|
||||
public async getByUid(uid: string, query?: Prisma.OfficeFoldersInclude) {
|
||||
return this.officeFoldersRepository.findOneByUid(uid, query);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description : Get a folder by uid
|
||||
* @throws {Error} If folder cannot be get by uid
|
||||
*/
|
||||
public async getByUidWithCustomers(uid: string) {
|
||||
return this.officeFoldersRepository.findOneByUidWithCustomers(uid);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -23,6 +23,14 @@ export default class CustomersService extends BaseService {
|
||||
* @throws {Error} If customer cannot be created
|
||||
*/
|
||||
public async create(customerEntity: Customer): Promise<Customers> {
|
||||
const customers = await this.get({
|
||||
where: {
|
||||
contact: {
|
||||
OR: [{ email: customerEntity.contact?.email }, { cell_phone_number: customerEntity.contact?.cell_phone_number }],
|
||||
},
|
||||
},
|
||||
});
|
||||
if(customers[0]) return customers[0];
|
||||
return this.customerRepository.create(customerEntity);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user