merged dev
This commit is contained in:
commit
51970e0435
@ -20,7 +20,7 @@ jobs:
|
|||||||
- setup_remote_docker:
|
- setup_remote_docker:
|
||||||
version: 20.10.12
|
version: 20.10.12
|
||||||
docker_layer_caching: true
|
docker_layer_caching: true
|
||||||
- run: docker login rg.fr-par.scw.cloud/lecoffre -u nologin -p $SCW_SECRET_KEY
|
- run: docker login rg.fr-par.scw.cloud/lecoffre -u nologin -p $SCW_SECRET_KEY_BIS
|
||||||
- run: docker build --tag rg.fr-par.scw.cloud/lecoffre/back:${CIRCLE_SHA1:0:7} .
|
- run: docker build --tag rg.fr-par.scw.cloud/lecoffre/back:${CIRCLE_SHA1:0:7} .
|
||||||
- run: docker push rg.fr-par.scw.cloud/lecoffre/back:${CIRCLE_SHA1:0:7}
|
- run: docker push rg.fr-par.scw.cloud/lecoffre/back:${CIRCLE_SHA1:0:7}
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ jobs:
|
|||||||
parameters:
|
parameters:
|
||||||
env:
|
env:
|
||||||
type: string
|
type: string
|
||||||
default: stg
|
default: ppd
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
- kubernetes/install-kubeconfig:
|
- kubernetes/install-kubeconfig:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
dockerPullSecret: docker-pull-secret
|
dockerPullSecret: docker-pull-secret
|
||||||
|
|
||||||
scwSecretKey: AgCgjF5QEzxT3GYTS5B6cmQ0e+0/qFWzKaUDSi+Vjc7RoameuvaIJvTXMBkS3he1oy1ulbB34v6vpZI2kxnGNqERA/U5BaYDAyfKSBwMAy4br7HVKhhuwkoF5qoG5JzJXseSmqB1U9vncVIGOZWzJc1Y4/eGlWcvLcLyfw2z/WEpyeNiWJfEhTYpJOB7gv0XnRb2U/JM3jRy1QgEUIk1WR6kgBalF+xaczPQ6uKh+PR2pqkbZa3WaKUrddmzNsgEz4d8PZMWt8IBwR2JOQEHUqCd34p/pJNyLdUgcdDhg02DKwn1oRoAxKTbAio/a7WrMbodjCb3TNWIYGal5mFmItZ7Ok/EBmUf4E85eOkTR+j8ynuuiexld3Q5Kw3o8LsHjgzVL9uP+T2rYaKkjtVt+YQRX1U8l9CrsdUEz0/wEBA0jwCWMfnh1qhD5pM/xwwjsEEAcK4rYV+Q7iAgGZZvZBCQ5aEHzrtn5D95tr1GZCV2hmrW6Seu+LKKLVBS1JmsuEsOuhudYsEK9m2RYVcxbjuS5eokKEjNrGobf2oB8rhBByavfw1JTBixR5JrI8lcYlnCa+oEhxXKJY+4Fx5SAB4YaLCMSo5vw6zsFQ3WKQzlEmCFt+EnapS+a+MGrdlwq07OHTDpvgk/1z39hopoCuhhKckGGfErLXsTYQvDOkFu+EPzgY7m7qDw/d9pSiht5tuSOkAqeOgm7tpNkUufZhaXmP+1aT7i+H5gq1JILGAmXzTI5Wc=
|
scwSecretKey: AgChoEnPitXp4Ny/rVMEcevaWKNVpyj2cJYAcq+yFqKwVwnLB+ffDvwqz9XBHu+6d4Nyyjkf37zUAMoaM21lEDWA7x3zfG2/D/j+rvX1qxzZgLD0mjBk7fGElVm332I6JA83oInes8AMMYEDPLElzHnpKRb9KtkIP4NzgOcCeW0ijft3N7Vroez6LEHsBPCA1I9XjKSkGEDvrO0MhWX3iJOlfz+SPMfJAV7rPawOs0ZmohTHrPW8qIvGDn8HCzKyU8zRBoMt+Ogpf5pH4U3JryEFuqD61KAQgablAM8edPIvsgNno9HAEuC2QtRLYA9aUhuKdaKuS58c9P2E80PHWXIlbpFCg6EugQTgNfnYp+3qDUNz8edeCfapYLvF4s9eCMGyMsGnpDR8EDNOyuGy7Y3l7okX8Xqu464gMp9E+hX7bHkcD6a4xfyIgJcWxsku0tm1TH1dpn4M1UXRuyZZif8P08nuE6MTUL67sAR9J1lpn4lVEL4kflk0pP2tZ5ncgPQFafJrRz05krMb0eU5tb2H4gs7ao/LL6idWo8MM9K1yr8lIuT5x2WW5CX+RjA+i50ex114V6vX3PNP5oVyt+DynTUB9QmXzVm3oLfDc3Cae1uqh7X0CFd+xiztJBtg0VtJaD/xUJcuWfY4cV2lERo9fRrykltzlJqiXHO4nowt8OtN0BcViVV8NJhPhYFzyb4ympxpOlTjm3GETuT2TYhUqdgS9nzleEAbOmOHZdIO2COunPE=
|
||||||
|
|
||||||
lecoffreBack:
|
lecoffreBack:
|
||||||
serviceAccountName: lecoffre-back-sa
|
serviceAccountName: lecoffre-back-sa
|
||||||
@ -18,10 +18,10 @@ lecoffreBack:
|
|||||||
limits:
|
limits:
|
||||||
memory: 2Gi
|
memory: 2Gi
|
||||||
ingress:
|
ingress:
|
||||||
host: api.stg.lecoffre.smart-chain.fr
|
host: api.ppd.lecoffre.smart-chain.fr
|
||||||
tls:
|
tls:
|
||||||
hosts:
|
hosts:
|
||||||
- api.stg.lecoffre.smart-chain.fr
|
- api.ppd.lecoffre.smart-chain.fr
|
||||||
secretName: api-tls
|
secretName: api-tls
|
||||||
annotations:
|
annotations:
|
||||||
kubernetes.io/ingress.class: nginx
|
kubernetes.io/ingress.class: nginx
|
||||||
@ -30,11 +30,11 @@ lecoffreBack:
|
|||||||
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
|
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
|
||||||
env:
|
env:
|
||||||
- key: .env
|
- key: .env
|
||||||
scwID: "id:a131edea-84e0-49d6-b4a8-20ab417220c9"
|
scwID: "id:2be9510b-bb1f-4fbe-ab3e-3dc11fb49051"
|
||||||
|
|
||||||
lecoffreCron:
|
lecoffreCron:
|
||||||
serviceAccountName: lecoffre-cron-sa
|
serviceAccountName: lecoffre-cron-sa
|
||||||
envSecrets: stg-env
|
envSecrets: ppd-env
|
||||||
command: "'sh', '-c', 'export $(xargs </etc/env/.env) && npm run cron'"
|
command: "'sh', '-c', 'export $(xargs </etc/env/.env) && npm run cron'"
|
||||||
imagePullSecrets:
|
imagePullSecrets:
|
||||||
- name: docker-pull-secret
|
- name: docker-pull-secret
|
||||||
|
@ -34,7 +34,7 @@ lecoffreBack:
|
|||||||
|
|
||||||
lecoffreCron:
|
lecoffreCron:
|
||||||
serviceAccountName: lecoffre-cron-sa
|
serviceAccountName: lecoffre-cron-sa
|
||||||
envSecrets: stg-env
|
envSecrets: prd-env
|
||||||
command: "'sh', '-c', 'export $(xargs </etc/env/.env) && npm run cron'"
|
command: "'sh', '-c', 'export $(xargs </etc/env/.env) && npm run cron'"
|
||||||
imagePullSecrets:
|
imagePullSecrets:
|
||||||
- name: docker-pull-secret
|
- name: docker-pull-secret
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
dockerPullSecret: id:47c1c301-1f02-49cc-9e5c-c1225a770aa8
|
dockerPullSecret: docker-pull-secret
|
||||||
|
|
||||||
scwSecretKey: AgChoEnPitXp4Ny/rVMEcevaWKNVpyj2cJYAcq+yFqKwVwnLB+ffDvwqz9XBHu+6d4Nyyjkf37zUAMoaM21lEDWA7x3zfG2/D/j+rvX1qxzZgLD0mjBk7fGElVm332I6JA83oInes8AMMYEDPLElzHnpKRb9KtkIP4NzgOcCeW0ijft3N7Vroez6LEHsBPCA1I9XjKSkGEDvrO0MhWX3iJOlfz+SPMfJAV7rPawOs0ZmohTHrPW8qIvGDn8HCzKyU8zRBoMt+Ogpf5pH4U3JryEFuqD61KAQgablAM8edPIvsgNno9HAEuC2QtRLYA9aUhuKdaKuS58c9P2E80PHWXIlbpFCg6EugQTgNfnYp+3qDUNz8edeCfapYLvF4s9eCMGyMsGnpDR8EDNOyuGy7Y3l7okX8Xqu464gMp9E+hX7bHkcD6a4xfyIgJcWxsku0tm1TH1dpn4M1UXRuyZZif8P08nuE6MTUL67sAR9J1lpn4lVEL4kflk0pP2tZ5ncgPQFafJrRz05krMb0eU5tb2H4gs7ao/LL6idWo8MM9K1yr8lIuT5x2WW5CX+RjA+i50ex114V6vX3PNP5oVyt+DynTUB9QmXzVm3oLfDc3Cae1uqh7X0CFd+xiztJBtg0VtJaD/xUJcuWfY4cV2lERo9fRrykltzlJqiXHO4nowt8OtN0BcViVV8NJhPhYFzyb4ympxpOlTjm3GETuT2TYhUqdgS9nzleEAbOmOHZdIO2COunPE=
|
scwSecretKey: 59bcf27d-bee3-4d14-8b4d-03fd6a8be6cd
|
||||||
|
|
||||||
lecoffreBack:
|
lecoffreBack:
|
||||||
serviceAccountName: lecoffre-back-sa
|
serviceAccountName: lecoffre-back-sa
|
||||||
@ -52,5 +52,3 @@ lecoffreCron:
|
|||||||
env:
|
env:
|
||||||
- key: .env
|
- key: .env
|
||||||
scwID: "id:2be9510b-bb1f-4fbe-ab3e-3dc11fb49051"
|
scwID: "id:2be9510b-bb1f-4fbe-ab3e-3dc11fb49051"
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,10 +19,10 @@ lecoffreBack:
|
|||||||
limits:
|
limits:
|
||||||
memory: 2Gi
|
memory: 2Gi
|
||||||
ingress:
|
ingress:
|
||||||
host: api.stg.lecoffre.smart-chain.fr
|
host: api.ppd.lecoffre.smart-chain.fr
|
||||||
tls:
|
tls:
|
||||||
hosts:
|
hosts:
|
||||||
- api.stg.lecoffre.smart-chain.fr
|
- api.ppd.lecoffre.smart-chain.fr
|
||||||
secretName: api-tls
|
secretName: api-tls
|
||||||
annotations:
|
annotations:
|
||||||
kubernetes.io/ingress.class: nginx
|
kubernetes.io/ingress.class: nginx
|
||||||
|
1604
package-lock.json
generated
1604
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -51,9 +51,11 @@
|
|||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"cron": "^2.3.1",
|
"cron": "^2.3.1",
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
|
"fp-ts": "^2.16.1",
|
||||||
"jsonwebtoken": "^9.0.0",
|
"jsonwebtoken": "^9.0.0",
|
||||||
"le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.79",
|
"le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.79",
|
||||||
"module-alias": "^2.2.2",
|
"module-alias": "^2.2.2",
|
||||||
|
"monocle-ts": "^2.3.13",
|
||||||
"multer": "^1.4.5-lts.1",
|
"multer": "^1.4.5-lts.1",
|
||||||
"next": "^13.1.5",
|
"next": "^13.1.5",
|
||||||
"node-cache": "^5.1.2",
|
"node-cache": "^5.1.2",
|
||||||
|
@ -6,6 +6,7 @@ import ApiController from "@Common/system/controller-pattern/ApiController";
|
|||||||
@Controller()
|
@Controller()
|
||||||
@Service()
|
@Service()
|
||||||
export default class HomeController extends ApiController {
|
export default class HomeController extends ApiController {
|
||||||
|
|
||||||
@Get("/")
|
@Get("/")
|
||||||
protected async get(req: Request, res: Response) {
|
protected async get(req: Request, res: Response) {
|
||||||
// const query = processFindManyQuery(req.query);
|
// const query = processFindManyQuery(req.query);
|
||||||
|
@ -93,8 +93,6 @@ export default class DocumentsController extends ApiController {
|
|||||||
try {
|
try {
|
||||||
//init Document resource with request body values
|
//init Document resource with request body values
|
||||||
const documentEntity = Document.hydrate<Document>(req.body);
|
const documentEntity = Document.hydrate<Document>(req.body);
|
||||||
console.log(documentEntity);
|
|
||||||
|
|
||||||
|
|
||||||
//validate document
|
//validate document
|
||||||
await validateOrReject(documentEntity, { groups: ["createDocument"], forbidUnknownValues: false });
|
await validateOrReject(documentEntity, { groups: ["createDocument"], forbidUnknownValues: false });
|
||||||
|
@ -54,7 +54,7 @@ export default class CustomerController extends ApiController {
|
|||||||
});
|
});
|
||||||
|
|
||||||
//success
|
//success
|
||||||
this.httpSuccess(response, accessToken);
|
this.httpSuccess(response, {accessToken});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.httpInternalError(response);
|
this.httpInternalError(response);
|
||||||
return;
|
return;
|
||||||
|
@ -5,10 +5,12 @@ import { Service } from "typedi";
|
|||||||
import AuthService from "@Services/common/AuthService/AuthService";
|
import AuthService from "@Services/common/AuthService/AuthService";
|
||||||
import { JwtPayload } from "jsonwebtoken";
|
import { JwtPayload } from "jsonwebtoken";
|
||||||
|
|
||||||
|
import IdNotService from "@Services/common/IdNotService/IdNotService";
|
||||||
|
|
||||||
@Controller()
|
@Controller()
|
||||||
@Service()
|
@Service()
|
||||||
export default class UserController extends ApiController {
|
export default class UserController extends ApiController {
|
||||||
constructor(private authService: AuthService) {
|
constructor(private authService: AuthService, private idNotService: IdNotService) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -19,16 +21,25 @@ export default class UserController extends ApiController {
|
|||||||
*/
|
*/
|
||||||
@Post("/api/v1/idnot/user/:code")
|
@Post("/api/v1/idnot/user/:code")
|
||||||
protected async getUserInfosFromIdnot(req: Request, response: Response) {
|
protected async getUserInfosFromIdnot(req: Request, response: Response) {
|
||||||
console.warn("/api/v1/idnot/user/:code used for test, should be removed");
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const code = req.params["code"];
|
const code = req.params["code"];
|
||||||
if (!code) throw new Error("code is required");
|
if (!code) throw new Error("code is required");
|
||||||
const token = await fetch("https://qual-connexion.idnot.fr/IdPOAuth2/token/idnot_idp_v1", { method: "POST" });
|
|
||||||
console.log(token);
|
const idNotToken = await this.idNotService.getIdNotToken(code);
|
||||||
//const user = await this.authService.getUserFromIdNotTokens(code!);
|
const user = await this.idNotService.getOrCreateUser(idNotToken);
|
||||||
//success
|
|
||||||
this.httpSuccess(response);
|
if(!user) {
|
||||||
|
this.httpUnauthorized(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await this.idNotService.updateUser(user.uid);
|
||||||
|
await this.idNotService.updateOffice(user.office_uid);
|
||||||
|
|
||||||
|
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) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
this.httpInternalError(response);
|
this.httpInternalError(response);
|
||||||
@ -55,7 +66,7 @@ export default class UserController extends ApiController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post("/api/v1/idnot/user/refresh-token")
|
@Post("/api/v1/idnot/user/auth/refresh-token")
|
||||||
protected async refreshToken(req: Request, response: Response) {
|
protected async refreshToken(req: Request, response: Response) {
|
||||||
try {
|
try {
|
||||||
const authHeader = req.headers["authorization"];
|
const authHeader = req.headers["authorization"];
|
||||||
@ -69,6 +80,7 @@ export default class UserController extends ApiController {
|
|||||||
let accessToken;
|
let accessToken;
|
||||||
this.authService.verifyRefreshToken(token, (err, userPayload) => {
|
this.authService.verifyRefreshToken(token, (err, userPayload) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
console.log(err);
|
||||||
this.httpUnauthorized(response);
|
this.httpUnauthorized(response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -80,7 +92,7 @@ export default class UserController extends ApiController {
|
|||||||
});
|
});
|
||||||
|
|
||||||
//success
|
//success
|
||||||
this.httpSuccess(response, accessToken);
|
this.httpSuccess(response, { accessToken });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.httpInternalError(response);
|
this.httpInternalError(response);
|
||||||
return;
|
return;
|
||||||
|
111
src/app/api/notary/OfficeFolderAnchorsController.ts
Normal file
111
src/app/api/notary/OfficeFolderAnchorsController.ts
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
import { Response, Request } from "express";
|
||||||
|
import { Controller, Get, Post } from "@ControllerPattern/index";
|
||||||
|
import ApiController from "@Common/system/controller-pattern/ApiController";
|
||||||
|
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 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";
|
||||||
|
|
||||||
|
@Controller()
|
||||||
|
@Service()
|
||||||
|
export default class OfficeFoldersController extends ApiController {
|
||||||
|
constructor(private secureService: SecureService, private officeFoldersService: OfficeFoldersService) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Create a new folder anchor
|
||||||
|
*/
|
||||||
|
@Post("/api/v1/notary/anchors/:uid", [authHandler, ruleHandler, folderHandler])
|
||||||
|
protected async post(req: Request, response: Response) {
|
||||||
|
try {
|
||||||
|
const uid = req.params["uid"];
|
||||||
|
|
||||||
|
if (!uid) {
|
||||||
|
this.httpBadRequest(response, "No uid provided");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const query = {
|
||||||
|
documents: {
|
||||||
|
include: {
|
||||||
|
files: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const officeFolderFound = await this.officeFoldersService.getByUid(uid, query);
|
||||||
|
|
||||||
|
if (!officeFolderFound) {
|
||||||
|
this.httpNotFoundRequest(response, "Office folder not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const officeFolder = OfficeFolder.hydrate<OfficeFolder>(officeFolderFound, { strategy: "excludeAll" });
|
||||||
|
const folderHashes = getFolderHashes(officeFolder);
|
||||||
|
|
||||||
|
if (folderHashes.length === 0) {
|
||||||
|
this.httpNotFoundRequest(response, "No file hash to anchor");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const sortedHashes = [...folderHashes].sort();
|
||||||
|
const anchor = await this.secureService.anchor(sortedHashes);
|
||||||
|
|
||||||
|
this.httpSuccess(response, anchor);
|
||||||
|
} catch (error) {
|
||||||
|
this.httpInternalError(response, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Verify a folder anchor status
|
||||||
|
*/
|
||||||
|
@Get("/api/v1/notary/anchors/:uid", [authHandler, ruleHandler, folderHandler])
|
||||||
|
protected async get(req: Request, response: Response) {
|
||||||
|
try {
|
||||||
|
const uid = req.params["uid"];
|
||||||
|
|
||||||
|
if (!uid) {
|
||||||
|
this.httpBadRequest(response, "No uid provided");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const query = {
|
||||||
|
documents: {
|
||||||
|
include: {
|
||||||
|
files: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const officeFolderFound = await this.officeFoldersService.getByUid(uid, query);
|
||||||
|
|
||||||
|
if (!officeFolderFound) {
|
||||||
|
this.httpNotFoundRequest(response, "Office folder not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const officeFolder = OfficeFolder.hydrate<OfficeFolder>(officeFolderFound, { strategy: "excludeAll" });
|
||||||
|
const folderHashes = getFolderHashes(officeFolder);
|
||||||
|
|
||||||
|
if (folderHashes.length === 0) {
|
||||||
|
this.httpNotFoundRequest(response, "No file hash to anchor");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const sortedHashes = [...folderHashes].sort();
|
||||||
|
const anchor = await this.secureService.verify(sortedHashes);
|
||||||
|
|
||||||
|
this.httpSuccess(response, anchor);
|
||||||
|
} catch (error) {
|
||||||
|
this.httpInternalError(response, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,7 @@ import { Controller, Get } from "@ControllerPattern/index";
|
|||||||
import ApiController from "@Common/system/controller-pattern/ApiController";
|
import ApiController from "@Common/system/controller-pattern/ApiController";
|
||||||
import UsersService from "@Services/notary/UsersService/UsersService";
|
import UsersService from "@Services/notary/UsersService/UsersService";
|
||||||
import { Service } from "typedi";
|
import { Service } from "typedi";
|
||||||
import User from "le-coffre-resources/dist/SuperAdmin";
|
import User from "le-coffre-resources/dist/Notary/User";
|
||||||
import { Prisma } from "@prisma/client";
|
import { Prisma } from "@prisma/client";
|
||||||
import authHandler from "@App/middlewares/AuthHandler";
|
import authHandler from "@App/middlewares/AuthHandler";
|
||||||
import ruleHandler from "@App/middlewares/RulesHandler";
|
import ruleHandler from "@App/middlewares/RulesHandler";
|
||||||
|
@ -41,10 +41,12 @@ import OfficeRolesControllerNotary from "./api/notary/OfficeRolesController";
|
|||||||
import FilesControllerCustomer from "./api/customer/FilesController";
|
import FilesControllerCustomer from "./api/customer/FilesController";
|
||||||
import DocumentsControllerCustomer from "./api/customer/DocumentsController";
|
import DocumentsControllerCustomer from "./api/customer/DocumentsController";
|
||||||
import OfficeFoldersController from "./api/customer/OfficeFoldersController";
|
import OfficeFoldersController from "./api/customer/OfficeFoldersController";
|
||||||
|
import OfficeFolderAnchorsController from "./api/notary/OfficeFolderAnchorsController";
|
||||||
import CustomersController from "./api/customer/CustomersController";
|
import CustomersController from "./api/customer/CustomersController";
|
||||||
import AppointmentsController from "./api/super-admin/AppointmentsController";
|
import AppointmentsController from "./api/super-admin/AppointmentsController";
|
||||||
import VotesController from "./api/super-admin/VotesController";
|
import VotesController from "./api/super-admin/VotesController";
|
||||||
import LiveVoteController from "./api/super-admin/LiveVoteController";
|
import LiveVoteController from "./api/super-admin/LiveVoteController";
|
||||||
|
|
||||||
import UserNotificationController from "./api/common/UserNotificationController";
|
import UserNotificationController from "./api/common/UserNotificationController";
|
||||||
|
|
||||||
|
|
||||||
@ -52,6 +54,7 @@ import UserNotificationController from "./api/common/UserNotificationController"
|
|||||||
* @description This allow to declare all controllers used in the application
|
* @description This allow to declare all controllers used in the application
|
||||||
*/
|
*/
|
||||||
export default {
|
export default {
|
||||||
|
|
||||||
start: () => {
|
start: () => {
|
||||||
Container.get(HomeController);
|
Container.get(HomeController);
|
||||||
Container.get(UsersControllerSuperAdmin);
|
Container.get(UsersControllerSuperAdmin);
|
||||||
@ -99,6 +102,7 @@ export default {
|
|||||||
Container.get(FilesControllerCustomer);
|
Container.get(FilesControllerCustomer);
|
||||||
Container.get(DocumentsControllerCustomer);
|
Container.get(DocumentsControllerCustomer);
|
||||||
Container.get(OfficeFoldersController);
|
Container.get(OfficeFoldersController);
|
||||||
|
Container.get(OfficeFolderAnchorsController);
|
||||||
Container.get(CustomersController);
|
Container.get(CustomersController);
|
||||||
Container.get(UserNotificationController);
|
Container.get(UserNotificationController);
|
||||||
},
|
},
|
||||||
|
@ -25,6 +25,9 @@ export class BackendVariables {
|
|||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
public readonly API_ROOT_URL!: string;
|
public readonly API_ROOT_URL!: string;
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
public readonly APP_HOST!: string;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
public readonly APP_LABEL!: string;
|
public readonly APP_LABEL!: string;
|
||||||
|
|
||||||
@ -34,6 +37,12 @@ export class BackendVariables {
|
|||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
public readonly APP_ROOT_URL!: string;
|
public readonly APP_ROOT_URL!: string;
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
public readonly IDNOT_BASE_URL!: string;
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
public readonly IDNOT_API_BASE_URL!: string;
|
||||||
|
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
public readonly IDNOT_CONNEXION_URL!: string;
|
public readonly IDNOT_CONNEXION_URL!: string;
|
||||||
|
|
||||||
@ -46,6 +55,9 @@ export class BackendVariables {
|
|||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
public readonly IDNOT_REDIRECT_URL!: string;
|
public readonly IDNOT_REDIRECT_URL!: string;
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
public readonly IDNOT_API_KEY!: string;
|
||||||
|
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
public readonly PINATA_API_KEY!: string;
|
public readonly PINATA_API_KEY!: string;
|
||||||
|
|
||||||
@ -64,11 +76,16 @@ export class BackendVariables {
|
|||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
public readonly MAILCHIMP_API_KEY!: string;
|
public readonly MAILCHIMP_API_KEY!: string;
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
public readonly SECURE_API_KEY!: string;
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
public readonly SECURE_API_BASE_URL!: string;
|
||||||
|
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
public readonly ENV!: string;
|
public readonly ENV!: string;
|
||||||
|
|
||||||
public constructor() {
|
public constructor() {
|
||||||
|
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
this.DATABASE_PORT = process.env["DATABASE_PORT"]!;
|
this.DATABASE_PORT = process.env["DATABASE_PORT"]!;
|
||||||
this.DATABASE_HOST = process.env["DATABASE_HOST"]!;
|
this.DATABASE_HOST = process.env["DATABASE_HOST"]!;
|
||||||
@ -77,21 +94,26 @@ export class BackendVariables {
|
|||||||
this.DATABASE_NAME = process.env["DATABASE_NAME"]!;
|
this.DATABASE_NAME = process.env["DATABASE_NAME"]!;
|
||||||
this.DATABASE_URL = process.env["DEV_PRISMA_STUDIO_DB_URL"]!;
|
this.DATABASE_URL = process.env["DEV_PRISMA_STUDIO_DB_URL"]!;
|
||||||
this.API_ROOT_URL = process.env["API_ROOT_URL"]!;
|
this.API_ROOT_URL = process.env["API_ROOT_URL"]!;
|
||||||
|
this.APP_HOST = process.env["APP_HOST"]!;
|
||||||
this.APP_PORT = process.env["APP_PORT"]!;
|
this.APP_PORT = process.env["APP_PORT"]!;
|
||||||
this.APP_ROOT_URL = process.env["APP_ROOT_URL"]!;
|
this.APP_ROOT_URL = process.env["APP_ROOT_URL"]!;
|
||||||
this.APP_LABEL = process.env["APP_LABEL"]!;
|
this.APP_LABEL = process.env["APP_LABEL"]!;
|
||||||
|
this.IDNOT_BASE_URL = process.env["IDNOT_BASE_URL"]!;
|
||||||
|
this.IDNOT_API_BASE_URL = process.env["IDNOT_API_BASE_URL"]!;
|
||||||
this.IDNOT_CONNEXION_URL = process.env["IDNOT_CONNEXION_URL"]!;
|
this.IDNOT_CONNEXION_URL = process.env["IDNOT_CONNEXION_URL"]!;
|
||||||
this.IDNOT_CLIENT_ID = process.env["IDNOT_CLIENT_ID"]!;
|
this.IDNOT_CLIENT_ID = process.env["IDNOT_CLIENT_ID"]!;
|
||||||
this.IDNOT_CLIENT_SECRET = process.env["IDNOT_CLIENT_SECRET"]!;
|
this.IDNOT_CLIENT_SECRET = process.env["IDNOT_CLIENT_SECRET"]!;
|
||||||
this.IDNOT_REDIRECT_URL = process.env["IDNOT_REDIRECT_URL"]!;
|
this.IDNOT_REDIRECT_URL = process.env["IDNOT_REDIRECT_URL"]!;
|
||||||
|
this.IDNOT_API_KEY = process.env["IDNOT_API_KEY"]!;
|
||||||
this.PINATA_API_KEY = process.env["PINATA_API_KEY"]!;
|
this.PINATA_API_KEY = process.env["PINATA_API_KEY"]!;
|
||||||
this.PINATA_API_SECRET = process.env["PINATA_API_SECRET"]!;
|
this.PINATA_API_SECRET = process.env["PINATA_API_SECRET"]!;
|
||||||
this.PINATA_GATEWAY = process.env["PINATA_GATEWAY"]!;
|
this.PINATA_GATEWAY = process.env["PINATA_GATEWAY"]!;
|
||||||
this.ACCESS_TOKEN_SECRET = process.env["ACCESS_TOKEN_SECRET"]!;
|
this.ACCESS_TOKEN_SECRET = process.env["ACCESS_TOKEN_SECRET"]!;
|
||||||
this.REFRESH_TOKEN_SECRET = process.env["REFRESH_TOKEN_SECRET"]!;
|
this.REFRESH_TOKEN_SECRET = process.env["REFRESH_TOKEN_SECRET"]!;
|
||||||
this.MAILCHIMP_API_KEY = process.env["MAILCHIMP_API_KEY"]!;
|
this.MAILCHIMP_API_KEY = process.env["MAILCHIMP_API_KEY"]!;
|
||||||
|
this.SECURE_API_KEY = process.env["SECURE_API_KEY"]!;
|
||||||
|
this.SECURE_API_BASE_URL = process.env["SECURE_API_BASE_URL"]!;
|
||||||
this.ENV = process.env["ENV"]!;
|
this.ENV = process.env["ENV"]!;
|
||||||
|
|
||||||
}
|
}
|
||||||
public async validate(groups?: string[]) {
|
public async validate(groups?: string[]) {
|
||||||
const validationOptions = groups ? { groups } : undefined;
|
const validationOptions = groups ? { groups } : undefined;
|
||||||
@ -99,7 +121,7 @@ export class BackendVariables {
|
|||||||
try {
|
try {
|
||||||
await validateOrReject(this, validationOptions);
|
await validateOrReject(this, validationOptions);
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
if (process.env["ENV"] === "dev") {
|
if (process.env["ENV"] === "dev" || process.env["ENV"] === 'stg') {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
throw new Error("Some env variables are required!");
|
throw new Error("Some env variables are required!");
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "offices" ADD COLUMN "checked_at" TIMESTAMP(3);
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "users" ADD COLUMN "checked_at" TIMESTAMP(3);
|
@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
Warnings:
|
||||||
|
|
||||||
|
- The values [ANCHORED] on the enum `EDocumentStatus` will be removed. If these variants are still used in the database, this will fail.
|
||||||
|
- You are about to drop the column `blockchain_anchor_uid` on the `documents` table. All the data in the column will be lost.
|
||||||
|
- You are about to drop the `blockchain_anchors` table. If the table is not empty, all the data it contains will be lost.
|
||||||
|
- A unique constraint covering the columns `[folder_anchor_uid]` on the table `office_folders` will be added. If there are existing duplicate values, this will fail.
|
||||||
|
- Added the required column `hash` to the `files` table without a default value. This is not possible if the table is not empty.
|
||||||
|
|
||||||
|
*/
|
||||||
|
-- CreateEnum
|
||||||
|
CREATE TYPE "EBlockchainName" AS ENUM ('TEZOS');
|
||||||
|
|
||||||
|
-- CreateEnum
|
||||||
|
CREATE TYPE "EAnchoringStatus" AS ENUM ('QUEUED', 'ATTEMPTING', 'VERIFIED_ON_CHAIN', 'VERIFYING_ON_CHAIN', 'ABANDONED');
|
||||||
|
|
||||||
|
-- AlterEnum
|
||||||
|
BEGIN;
|
||||||
|
CREATE TYPE "EDocumentStatus_new" AS ENUM ('ASKED', 'DEPOSITED', 'VALIDATED', 'REFUSED');
|
||||||
|
ALTER TABLE "documents" ALTER COLUMN "document_status" DROP DEFAULT;
|
||||||
|
ALTER TABLE "document_history" ALTER COLUMN "document_status" DROP DEFAULT;
|
||||||
|
ALTER TABLE "documents" ALTER COLUMN "document_status" TYPE "EDocumentStatus_new" USING ("document_status"::text::"EDocumentStatus_new");
|
||||||
|
ALTER TABLE "document_history" ALTER COLUMN "document_status" TYPE "EDocumentStatus_new" USING ("document_status"::text::"EDocumentStatus_new");
|
||||||
|
ALTER TYPE "EDocumentStatus" RENAME TO "EDocumentStatus_old";
|
||||||
|
ALTER TYPE "EDocumentStatus_new" RENAME TO "EDocumentStatus";
|
||||||
|
DROP TYPE "EDocumentStatus_old";
|
||||||
|
ALTER TABLE "documents" ALTER COLUMN "document_status" SET DEFAULT 'ASKED';
|
||||||
|
ALTER TABLE "document_history" ALTER COLUMN "document_status" SET DEFAULT 'ASKED';
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
-- DropForeignKey
|
||||||
|
ALTER TABLE "documents" DROP CONSTRAINT "documents_blockchain_anchor_uid_fkey";
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "documents" DROP COLUMN "blockchain_anchor_uid";
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "files" ADD COLUMN "hash" VARCHAR(255) NOT NULL;
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "office_folders" ADD COLUMN "folder_anchor_uid" VARCHAR(255);
|
||||||
|
|
||||||
|
-- DropTable
|
||||||
|
DROP TABLE "blockchain_anchors";
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "office_folder_anchors" (
|
||||||
|
"uid" TEXT NOT NULL,
|
||||||
|
"hash_sources" TEXT[],
|
||||||
|
"root_hash" VARCHAR(255) NOT NULL,
|
||||||
|
"blockchain" "EBlockchainName" NOT NULL DEFAULT 'TEZOS',
|
||||||
|
"status" "EAnchoringStatus" NOT NULL DEFAULT 'QUEUED',
|
||||||
|
"anchor_nb_try" INTEGER NOT NULL DEFAULT 0,
|
||||||
|
"anchored_at" TIMESTAMP(3),
|
||||||
|
"tx_id" VARCHAR(255),
|
||||||
|
"tx_link" VARCHAR(255),
|
||||||
|
"tx_hash" VARCHAR(255),
|
||||||
|
"created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updated_at" TIMESTAMP(3),
|
||||||
|
|
||||||
|
CONSTRAINT "office_folder_anchors_pkey" PRIMARY KEY ("uid")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "office_folder_anchors_uid_key" ON "office_folder_anchors"("uid");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "office_folders_folder_anchor_uid_key" ON "office_folders"("folder_anchor_uid");
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "office_folders" ADD CONSTRAINT "office_folders_folder_anchor_uid_fkey" FOREIGN KEY ("folder_anchor_uid") REFERENCES "office_folder_anchors"("uid") ON DELETE SET NULL ON UPDATE CASCADE;
|
@ -61,6 +61,7 @@ model Users {
|
|||||||
office_role_uid String? @db.VarChar(255)
|
office_role_uid String? @db.VarChar(255)
|
||||||
created_at DateTime? @default(now())
|
created_at DateTime? @default(now())
|
||||||
updated_at DateTime? @updatedAt
|
updated_at DateTime? @updatedAt
|
||||||
|
checked_at DateTime?
|
||||||
office_membership Offices @relation(fields: [office_uid], references: [uid], onDelete: Cascade)
|
office_membership Offices @relation(fields: [office_uid], references: [uid], onDelete: Cascade)
|
||||||
office_uid String @db.VarChar(255)
|
office_uid String @db.VarChar(255)
|
||||||
office_folders OfficeFolders[] @relation("OfficeFolderHasStakeholders")
|
office_folders OfficeFolders[] @relation("OfficeFolderHasStakeholders")
|
||||||
@ -81,6 +82,7 @@ model Offices {
|
|||||||
office_status EOfficeStatus @default(DESACTIVATED)
|
office_status EOfficeStatus @default(DESACTIVATED)
|
||||||
created_at DateTime? @default(now())
|
created_at DateTime? @default(now())
|
||||||
updated_at DateTime? @updatedAt
|
updated_at DateTime? @updatedAt
|
||||||
|
checked_at DateTime?
|
||||||
deed_types DeedTypes[]
|
deed_types DeedTypes[]
|
||||||
users Users[]
|
users Users[]
|
||||||
office_folders OfficeFolders[]
|
office_folders OfficeFolders[]
|
||||||
@ -142,17 +144,41 @@ model OfficeFolders {
|
|||||||
customers Customers[] @relation("OfficeFolderHasCustomers")
|
customers Customers[] @relation("OfficeFolderHasCustomers")
|
||||||
documents Documents[]
|
documents Documents[]
|
||||||
|
|
||||||
|
folder_anchor OfficeFolderAnchors? @relation(fields: [folder_anchor_uid], references: [uid])
|
||||||
|
folder_anchor_uid String? @unique @db.VarChar(255)
|
||||||
|
|
||||||
@@unique([folder_number, office_uid])
|
@@unique([folder_number, office_uid])
|
||||||
@@map("office_folders")
|
@@map("office_folders")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
model OfficeFolderAnchors {
|
||||||
|
uid String @id @unique @default(uuid())
|
||||||
|
|
||||||
|
hash_sources String[]
|
||||||
|
root_hash String @db.VarChar(255)
|
||||||
|
|
||||||
|
blockchain EBlockchainName @default(TEZOS)
|
||||||
|
status EAnchoringStatus @default(QUEUED)
|
||||||
|
anchor_nb_try Int @default(0)
|
||||||
|
|
||||||
|
anchored_at DateTime?
|
||||||
|
tx_id String? @db.VarChar(255)
|
||||||
|
tx_link String? @db.VarChar(255)
|
||||||
|
tx_hash String? @db.VarChar(255)
|
||||||
|
|
||||||
|
folder OfficeFolders?
|
||||||
|
|
||||||
|
created_at DateTime? @default(now())
|
||||||
|
updated_at DateTime? @updatedAt
|
||||||
|
|
||||||
|
@@map("office_folder_anchors")
|
||||||
|
}
|
||||||
|
|
||||||
model Documents {
|
model Documents {
|
||||||
uid String @id @unique @default(uuid())
|
uid String @id @unique @default(uuid())
|
||||||
document_status EDocumentStatus @default(ASKED)
|
document_status EDocumentStatus @default(ASKED)
|
||||||
document_type DocumentTypes @relation(fields: [document_type_uid], references: [uid])
|
document_type DocumentTypes @relation(fields: [document_type_uid], references: [uid])
|
||||||
document_type_uid String @db.VarChar(255)
|
document_type_uid String @db.VarChar(255)
|
||||||
blockchain_anchor BlockchainAnchors? @relation(fields: [blockchain_anchor_uid], references: [uid])
|
|
||||||
blockchain_anchor_uid String? @db.VarChar(255)
|
|
||||||
folder OfficeFolders @relation(fields: [folder_uid], references: [uid])
|
folder OfficeFolders @relation(fields: [folder_uid], references: [uid])
|
||||||
folder_uid String @db.VarChar(255)
|
folder_uid String @db.VarChar(255)
|
||||||
depositor Customers @relation(fields: [depositor_uid], references: [uid], onDelete: Cascade)
|
depositor Customers @relation(fields: [depositor_uid], references: [uid], onDelete: Cascade)
|
||||||
@ -184,6 +210,7 @@ model Files {
|
|||||||
file_path String @unique @db.VarChar(255)
|
file_path String @unique @db.VarChar(255)
|
||||||
file_name String @db.VarChar(255)
|
file_name String @db.VarChar(255)
|
||||||
mimetype String @db.VarChar(255)
|
mimetype String @db.VarChar(255)
|
||||||
|
hash String @db.VarChar(255)
|
||||||
size Int
|
size Int
|
||||||
archived_at DateTime?
|
archived_at DateTime?
|
||||||
key String? @db.VarChar(255)
|
key String? @db.VarChar(255)
|
||||||
@ -193,16 +220,6 @@ model Files {
|
|||||||
@@map("files")
|
@@map("files")
|
||||||
}
|
}
|
||||||
|
|
||||||
model BlockchainAnchors {
|
|
||||||
uid String @id @unique @default(uuid())
|
|
||||||
smartSigJobId String @unique @db.VarChar(255)
|
|
||||||
created_at DateTime? @default(now())
|
|
||||||
updated_at DateTime? @updatedAt
|
|
||||||
documents Documents[]
|
|
||||||
|
|
||||||
@@map("blockchain_anchors")
|
|
||||||
}
|
|
||||||
|
|
||||||
model DocumentTypes {
|
model DocumentTypes {
|
||||||
uid String @id @unique @default(uuid())
|
uid String @id @unique @default(uuid())
|
||||||
name String @db.VarChar(255)
|
name String @db.VarChar(255)
|
||||||
@ -355,7 +372,6 @@ enum EDocumentStatus {
|
|||||||
ASKED
|
ASKED
|
||||||
DEPOSITED
|
DEPOSITED
|
||||||
VALIDATED
|
VALIDATED
|
||||||
ANCHORED
|
|
||||||
REFUSED
|
REFUSED
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,3 +384,15 @@ enum EAppointmentStatus {
|
|||||||
OPEN
|
OPEN
|
||||||
CLOSED
|
CLOSED
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum EBlockchainName {
|
||||||
|
TEZOS
|
||||||
|
}
|
||||||
|
|
||||||
|
enum EAnchoringStatus {
|
||||||
|
QUEUED
|
||||||
|
ATTEMPTING
|
||||||
|
VERIFIED_ON_CHAIN
|
||||||
|
VERIFYING_ON_CHAIN
|
||||||
|
ABANDONED
|
||||||
|
}
|
||||||
|
@ -1,10 +1,22 @@
|
|||||||
import { ECivility, ECustomerStatus, EFolderStatus, EOfficeStatus, Prisma, PrismaClient } from "@prisma/client";
|
import { ECivility, ECustomerStatus, EFolderStatus, EOfficeStatus, Prisma, PrismaClient } from "@prisma/client";
|
||||||
import User, { Address, Contact, Customer, Deed, DeedType, DocumentType, Office, OfficeFolder, OfficeRole, Role, Rule } from "le-coffre-resources/dist/SuperAdmin";
|
import User, {
|
||||||
|
Address,
|
||||||
|
Contact,
|
||||||
|
Customer,
|
||||||
|
Deed,
|
||||||
|
DeedType,
|
||||||
|
DocumentType,
|
||||||
|
Office,
|
||||||
|
OfficeFolder,
|
||||||
|
OfficeRole,
|
||||||
|
Role,
|
||||||
|
Rule,
|
||||||
|
} from "le-coffre-resources/dist/SuperAdmin";
|
||||||
|
|
||||||
import "module-alias/register";
|
import "module-alias/register";
|
||||||
|
|
||||||
export default async function main() {
|
export default async function main() {
|
||||||
try{
|
try {
|
||||||
const prisma = new PrismaClient();
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
const randomString = () => {
|
const randomString = () => {
|
||||||
@ -586,20 +598,8 @@ export default async function main() {
|
|||||||
updated_at: new Date(),
|
updated_at: new Date(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "PUT users",
|
name: "POST deeds",
|
||||||
label: "Modification des utilisateurs",
|
label: "Création des actes",
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "PUT offices",
|
|
||||||
label: "Modification des offices",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "PUT customers",
|
|
||||||
label: "Modification des clients",
|
|
||||||
created_at: new Date(),
|
created_at: new Date(),
|
||||||
updated_at: new Date(),
|
updated_at: new Date(),
|
||||||
},
|
},
|
||||||
@ -610,98 +610,8 @@ export default async function main() {
|
|||||||
updated_at: new Date(),
|
updated_at: new Date(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "PUT deed-types",
|
name: "DELETE deeds",
|
||||||
label: "Modification des types d'actes",
|
label: "Suppression des actes",
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "PUT documents",
|
|
||||||
label: "Modification des documents",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "PUT document-types",
|
|
||||||
label: "Modification des types de documents",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "PUT files",
|
|
||||||
label: "Modification des fichiers",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "PUT folders",
|
|
||||||
label: "Modification des dossiers",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "PUT roles",
|
|
||||||
label: "Modification des rôles",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "PUT rules",
|
|
||||||
label: "Modification des droits",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "PUT office-roles",
|
|
||||||
label: "Modification des rôles d'office",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "POST users",
|
|
||||||
label: "Création des utilisateurs",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "POST offices",
|
|
||||||
label: "Création des offices",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "POST customers",
|
|
||||||
label: "Création des clients",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "POST deeds",
|
|
||||||
label: "Création des actes",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "POST deed-types",
|
|
||||||
label: "Création des types d'actes",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "POST documents",
|
|
||||||
label: "Création des documents",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "POST document-types",
|
|
||||||
label: "Création des types de documents",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "POST files",
|
|
||||||
label: "Création des fichiers",
|
|
||||||
created_at: new Date(),
|
created_at: new Date(),
|
||||||
updated_at: new Date(),
|
updated_at: new Date(),
|
||||||
},
|
},
|
||||||
@ -712,68 +622,8 @@ export default async function main() {
|
|||||||
updated_at: new Date(),
|
updated_at: new Date(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "POST roles",
|
name: "PUT folders",
|
||||||
label: "Création des rôles",
|
label: "Modification des dossiers",
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "POST rules",
|
|
||||||
label: "Création des droits",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "POST office-roles",
|
|
||||||
label: "Création des rôles d'office",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "DELETE users",
|
|
||||||
label: "Suppression des utilisateurs",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "DELETE offices",
|
|
||||||
label: "Suppression des offices",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "DELETE customers",
|
|
||||||
label: "Suppression des clients",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "DELETE deeds",
|
|
||||||
label: "Suppression des actes",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "DELETE deed-types",
|
|
||||||
label: "Suppression des types d'actes",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "DELETE documents",
|
|
||||||
label: "Suppression des documents",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "DELETE document-types",
|
|
||||||
label: "Suppression des types de documents",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "DELETE files",
|
|
||||||
label: "Suppression des fichiers",
|
|
||||||
created_at: new Date(),
|
created_at: new Date(),
|
||||||
updated_at: new Date(),
|
updated_at: new Date(),
|
||||||
},
|
},
|
||||||
@ -784,14 +634,98 @@ export default async function main() {
|
|||||||
updated_at: new Date(),
|
updated_at: new Date(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "DELETE roles",
|
name: "POST documents",
|
||||||
label: "Suppression des rôles",
|
label: "Création des documents",
|
||||||
created_at: new Date(),
|
created_at: new Date(),
|
||||||
updated_at: new Date(),
|
updated_at: new Date(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "DELETE rules",
|
name: "PUT documents",
|
||||||
label: "Suppression des droits",
|
label: "Modification des documents",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "DELETE documents",
|
||||||
|
label: "Suppression des documents",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "POST customers",
|
||||||
|
label: "Création des clients",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PUT customers",
|
||||||
|
label: "Modification des clients",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "DELETE customers",
|
||||||
|
label: "Suppression des clients",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "POST anchors",
|
||||||
|
label: "Ancrer un dossier",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GET anchors",
|
||||||
|
label: "Vérifier l'ancrage un dossier",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "POST deed-types",
|
||||||
|
label: "Création des types d'actes",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PUT deed-types",
|
||||||
|
label: "Modification des types d'actes",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "DELETE deed-types",
|
||||||
|
label: "Suppression des types d'actes",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "POST document-types",
|
||||||
|
label: "Création des types de documents",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PUT document-types",
|
||||||
|
label: "Modification des types de documents",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "DELETE document-types",
|
||||||
|
label: "Suppression des types de documents",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "POST office-roles",
|
||||||
|
label: "Création des rôles d'office",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PUT office-roles",
|
||||||
|
label: "Modification des rôles d'office",
|
||||||
created_at: new Date(),
|
created_at: new Date(),
|
||||||
updated_at: new Date(),
|
updated_at: new Date(),
|
||||||
},
|
},
|
||||||
@ -801,6 +735,24 @@ export default async function main() {
|
|||||||
created_at: new Date(),
|
created_at: new Date(),
|
||||||
updated_at: new Date(),
|
updated_at: new Date(),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "DELETE office-roles",
|
||||||
|
label: "Suppression des rôles d'office",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PUT users",
|
||||||
|
label: "Modification des utilisateurs",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PUT offices",
|
||||||
|
label: "Modification des offices",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const roles: Role[] = [
|
const roles: Role[] = [
|
||||||
@ -816,21 +768,21 @@ export default async function main() {
|
|||||||
label: "Administrateur",
|
label: "Administrateur",
|
||||||
created_at: new Date(),
|
created_at: new Date(),
|
||||||
updated_at: new Date(),
|
updated_at: new Date(),
|
||||||
rules: rules.slice(0, 33),
|
rules: rules.slice(0, 35),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "notary",
|
name: "notary",
|
||||||
label: "Notaire",
|
label: "Notaire",
|
||||||
created_at: new Date(),
|
created_at: new Date(),
|
||||||
updated_at: new Date(),
|
updated_at: new Date(),
|
||||||
rules: rules.slice(0, 22),
|
rules: rules.slice(0, 25),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "default",
|
name: "default",
|
||||||
label: "Utilisateur",
|
label: "Utilisateur",
|
||||||
created_at: new Date(),
|
created_at: new Date(),
|
||||||
updated_at: new Date(),
|
updated_at: new Date(),
|
||||||
rules: rules.slice(0, 11),
|
rules: rules.slice(0,1),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -840,7 +792,7 @@ export default async function main() {
|
|||||||
created_at: new Date(),
|
created_at: new Date(),
|
||||||
updated_at: new Date(),
|
updated_at: new Date(),
|
||||||
office: offices[0]!,
|
office: offices[0]!,
|
||||||
rules: rules.slice(0, 33),
|
rules: rules.slice(0, 35),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Collaborateur",
|
name: "Collaborateur",
|
||||||
@ -848,7 +800,7 @@ export default async function main() {
|
|||||||
updated_at: new Date(),
|
updated_at: new Date(),
|
||||||
office: offices[0]!,
|
office: offices[0]!,
|
||||||
rules: rules.slice(0, 22),
|
rules: rules.slice(0, 22),
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const users: User[] = [
|
const users: User[] = [
|
||||||
@ -895,6 +847,214 @@ export default async function main() {
|
|||||||
role: roles[3],
|
role: roles[3],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
const documentTypes: DocumentType[] = [
|
||||||
|
{
|
||||||
|
archived_at: null,
|
||||||
|
name: "Document d'identité",
|
||||||
|
office: offices[0],
|
||||||
|
private_description:
|
||||||
|
"Document officiel d'identification utilisé par plusieurs personnes pour prouver leur identité et leur nationalité (CNI, passeport)",
|
||||||
|
public_description:
|
||||||
|
"Document officiel d'identification utilisé par plusieurs personnes pour prouver leur identité et leur nationalité (CNI, passeport)",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
archived_at: null,
|
||||||
|
name: "Taxe Foncière",
|
||||||
|
office: offices[0],
|
||||||
|
private_description:
|
||||||
|
"Impôt annuel imposé sur les propriétés foncières et utilisé pour financer les services publics locaux.",
|
||||||
|
public_description:
|
||||||
|
"Impôt annuel imposé sur les propriétés foncières et utilisé pour financer les services publics locaux.",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
archived_at: null,
|
||||||
|
name: "Contrat Mariage",
|
||||||
|
office: offices[0],
|
||||||
|
private_description: "Accord légal qui établit les droits et les obligations entre deux personnes s'unissant en mariage.",
|
||||||
|
public_description: "Accord légal qui établit les droits et les obligations entre deux personnes s'unissant en mariage.",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
archived_at: null,
|
||||||
|
name: "Livret de famille",
|
||||||
|
office: offices[0],
|
||||||
|
private_description:
|
||||||
|
"Document officiel qui enregistre les détails et les événements familiaux tels que les mariages, les naissances et les décès d'un couple et de leurs enfants.",
|
||||||
|
public_description:
|
||||||
|
"Document officiel qui enregistre les détails et les événements familiaux tels que les mariages, les naissances et les décès d'un couple et de leurs enfants.",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
archived_at: null,
|
||||||
|
name: "Bail commercial",
|
||||||
|
office: offices[0],
|
||||||
|
private_description:
|
||||||
|
"Contrat légal entre un propriétaire et un locataire pour la location d'un bien immobilier utilisé à des fins commerciales ou professionnelles.",
|
||||||
|
public_description:
|
||||||
|
"Contrat légal entre un propriétaire et un locataire pour la location d'un bien immobilier utilisé à des fins commerciales ou professionnelles.",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
archived_at: null,
|
||||||
|
name: "Statuts SCI",
|
||||||
|
office: offices[0],
|
||||||
|
private_description:
|
||||||
|
"Document légal qui définit les règles et les dispositions régissant la Société Civile Immobilière (SCI).",
|
||||||
|
public_description:
|
||||||
|
"Document légal qui définit les règles et les dispositions régissant la Société Civile Immobilière (SCI).",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
archived_at: null,
|
||||||
|
name: "Avis de taxe foncière",
|
||||||
|
office: offices[0],
|
||||||
|
private_description: "Notification officielle indiquant le montant de l'impôt foncier dû sur une propriété.",
|
||||||
|
public_description: "Notification officielle indiquant le montant de l'impôt foncier dû sur une propriété.",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
archived_at: null,
|
||||||
|
name: "Appel de charge de copropriété",
|
||||||
|
office: offices[0],
|
||||||
|
private_description:
|
||||||
|
"Document envoyé aux copropriétaires pour les informer des dépenses et des charges communes liées à la gestion et à l'entretien de l'immeuble.",
|
||||||
|
public_description:
|
||||||
|
"Document envoyé aux copropriétaires pour les informer des dépenses et des charges communes liées à la gestion et à l'entretien de l'immeuble.",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
archived_at: null,
|
||||||
|
name: "PVAG",
|
||||||
|
office: offices[0],
|
||||||
|
private_description:
|
||||||
|
"Compte rendu écrit des discussions, décisions et résolutions prises lors d'une réunion d'assemblée générale de copropriété.",
|
||||||
|
public_description:
|
||||||
|
"Compte rendu écrit des discussions, décisions et résolutions prises lors d'une réunion d'assemblée générale de copropriété.",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
archived_at: null,
|
||||||
|
name: "Règlement de copropriété",
|
||||||
|
office: offices[0],
|
||||||
|
private_description:
|
||||||
|
"Document juridique qui établit les règles et les droits des copropriétaires d'un immeuble en copropriété.",
|
||||||
|
public_description:
|
||||||
|
"Document juridique qui établit les règles et les droits des copropriétaires d'un immeuble en copropriété.",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
archived_at: null,
|
||||||
|
name: "Titre de propriété",
|
||||||
|
office: offices[0],
|
||||||
|
private_description: "Document légal qui atteste de la propriété d'un bien immobilier et en identifie le propriétaire.",
|
||||||
|
public_description: "Document légal qui atteste de la propriété d'un bien immobilier et en identifie le propriétaire.",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
archived_at: null,
|
||||||
|
name: "Plan et loi carrez",
|
||||||
|
office: offices[0],
|
||||||
|
private_description:
|
||||||
|
"Document officiel qui mesure la superficie d'un lot ou d'un bien immobilier, conformément à la loi Carrez qui encadre les transactions immobilières.",
|
||||||
|
public_description:
|
||||||
|
"Document officiel qui mesure la superficie d'un lot ou d'un bien immobilier, conformément à la loi Carrez qui encadre les transactions immobilières.",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
archived_at: null,
|
||||||
|
name: "CNI",
|
||||||
|
office: offices[0],
|
||||||
|
private_description:
|
||||||
|
"Document officiel d'identification délivré par l'État pour prouver l'identité et la nationalité d'une personne.",
|
||||||
|
public_description:
|
||||||
|
"Document officiel d'identification délivré par l'État pour prouver l'identité et la nationalité d'une personne.",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
archived_at: null,
|
||||||
|
name: "Modifications règlement copropriété (plusieurs)",
|
||||||
|
office: offices[0],
|
||||||
|
private_description:
|
||||||
|
"Documents légaux qui apportent des changements ou des ajustements aux règles et dispositions du règlement de copropriété initial.",
|
||||||
|
public_description:
|
||||||
|
"Documents légaux qui apportent des changements ou des ajustements aux règles et dispositions du règlement de copropriété initial.",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
archived_at: null,
|
||||||
|
name: "Avis de décès",
|
||||||
|
office: offices[0],
|
||||||
|
private_description:
|
||||||
|
"Notification officielle délivrée par les autorités compétentes pour informer du décès d'une personne.",
|
||||||
|
public_description: "Notification officielle délivrée par les autorités compétentes pour informer du décès d'une personne.",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
archived_at: null,
|
||||||
|
name: "Lettre de mission",
|
||||||
|
office: offices[0],
|
||||||
|
private_description:
|
||||||
|
"Document contractuel qui définit les termes et les objectifs d'une mission confiée à une personne ou à une entreprise.",
|
||||||
|
public_description:
|
||||||
|
"Document contractuel qui définit les termes et les objectifs d'une mission confiée à une personne ou à une entreprise.",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
archived_at: null,
|
||||||
|
name: "DPE",
|
||||||
|
office: offices[0],
|
||||||
|
private_description: "Diagnostic de Performance Energétique.",
|
||||||
|
public_description: "Diagnostic de Performance Energétique.",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
archived_at: null,
|
||||||
|
name: "RIB",
|
||||||
|
office: offices[0],
|
||||||
|
private_description: "Relevé d'identité bancaire ou IBAN.",
|
||||||
|
public_description: "Relevé d'identité bancaire ou IBAN.",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
archived_at: null,
|
||||||
|
name: "Acte d'achat par la SCI",
|
||||||
|
office: offices[0],
|
||||||
|
private_description: "Acte d'achat par la SCI.",
|
||||||
|
public_description: "Acte d'achat par la SCI.",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
archived_at: null,
|
||||||
|
name: "Other",
|
||||||
|
office: offices[0],
|
||||||
|
private_description: "Other",
|
||||||
|
public_description: "Other",
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
const deedTypes: DeedType[] = [
|
const deedTypes: DeedType[] = [
|
||||||
{
|
{
|
||||||
@ -904,6 +1064,7 @@ export default async function main() {
|
|||||||
office: offices[0],
|
office: offices[0],
|
||||||
created_at: new Date(),
|
created_at: new Date(),
|
||||||
updated_at: new Date(),
|
updated_at: new Date(),
|
||||||
|
document_types: documentTypes.slice(0, 4),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Acte de vente",
|
name: "Acte de vente",
|
||||||
@ -912,6 +1073,7 @@ export default async function main() {
|
|||||||
office: offices[0],
|
office: offices[0],
|
||||||
created_at: new Date(),
|
created_at: new Date(),
|
||||||
updated_at: new Date(),
|
updated_at: new Date(),
|
||||||
|
document_types: documentTypes.slice(0, 4),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Acte de succession",
|
name: "Acte de succession",
|
||||||
@ -920,6 +1082,7 @@ export default async function main() {
|
|||||||
office: offices[0],
|
office: offices[0],
|
||||||
created_at: new Date(),
|
created_at: new Date(),
|
||||||
updated_at: new Date(),
|
updated_at: new Date(),
|
||||||
|
document_types: documentTypes.slice(0, 4),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Acte de vente de maison individuelle",
|
name: "Acte de vente de maison individuelle",
|
||||||
@ -928,6 +1091,7 @@ export default async function main() {
|
|||||||
office: offices[0],
|
office: offices[0],
|
||||||
created_at: new Date(),
|
created_at: new Date(),
|
||||||
updated_at: new Date(),
|
updated_at: new Date(),
|
||||||
|
document_types: documentTypes.slice(0, 4),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -1039,209 +1203,6 @@ export default async function main() {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const documentTypes: DocumentType[] = [
|
|
||||||
{
|
|
||||||
archived_at: null,
|
|
||||||
name: "Document d'identité",
|
|
||||||
office: offices[0],
|
|
||||||
private_description:
|
|
||||||
"Document officiel d'identification utilisé par plusieurs personnes pour prouver leur identité et leur nationalité (CNI, passeport)",
|
|
||||||
public_description:
|
|
||||||
"Document officiel d'identification utilisé par plusieurs personnes pour prouver leur identité et leur nationalité (CNI, passeport)",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
archived_at: null,
|
|
||||||
name: "Taxe Foncière",
|
|
||||||
office: offices[0],
|
|
||||||
private_description: "Impôt annuel imposé sur les propriétés foncières et utilisé pour financer les services publics locaux.",
|
|
||||||
public_description: "Impôt annuel imposé sur les propriétés foncières et utilisé pour financer les services publics locaux.",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
archived_at: null,
|
|
||||||
name: "Contrat Mariage",
|
|
||||||
office: offices[0],
|
|
||||||
private_description: "Accord légal qui établit les droits et les obligations entre deux personnes s'unissant en mariage.",
|
|
||||||
public_description: "Accord légal qui établit les droits et les obligations entre deux personnes s'unissant en mariage.",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
archived_at: null,
|
|
||||||
name: "Livret de famille",
|
|
||||||
office: offices[0],
|
|
||||||
private_description:
|
|
||||||
"Document officiel qui enregistre les détails et les événements familiaux tels que les mariages, les naissances et les décès d'un couple et de leurs enfants.",
|
|
||||||
public_description:
|
|
||||||
"Document officiel qui enregistre les détails et les événements familiaux tels que les mariages, les naissances et les décès d'un couple et de leurs enfants.",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
archived_at: null,
|
|
||||||
name: "Bail commercial",
|
|
||||||
office: offices[0],
|
|
||||||
private_description:
|
|
||||||
"Contrat légal entre un propriétaire et un locataire pour la location d'un bien immobilier utilisé à des fins commerciales ou professionnelles.",
|
|
||||||
public_description:
|
|
||||||
"Contrat légal entre un propriétaire et un locataire pour la location d'un bien immobilier utilisé à des fins commerciales ou professionnelles.",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
archived_at: null,
|
|
||||||
name: "Statuts SCI",
|
|
||||||
office: offices[0],
|
|
||||||
private_description: "Document légal qui définit les règles et les dispositions régissant la Société Civile Immobilière (SCI).",
|
|
||||||
public_description: "Document légal qui définit les règles et les dispositions régissant la Société Civile Immobilière (SCI).",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
archived_at: null,
|
|
||||||
name: "Avis de taxe foncière",
|
|
||||||
office: offices[0],
|
|
||||||
private_description: "Notification officielle indiquant le montant de l'impôt foncier dû sur une propriété.",
|
|
||||||
public_description: "Notification officielle indiquant le montant de l'impôt foncier dû sur une propriété.",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
archived_at: null,
|
|
||||||
name: "Appel de charge de copropriété",
|
|
||||||
office: offices[0],
|
|
||||||
private_description:
|
|
||||||
"Document envoyé aux copropriétaires pour les informer des dépenses et des charges communes liées à la gestion et à l'entretien de l'immeuble.",
|
|
||||||
public_description:
|
|
||||||
"Document envoyé aux copropriétaires pour les informer des dépenses et des charges communes liées à la gestion et à l'entretien de l'immeuble.",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
archived_at: null,
|
|
||||||
name: "PVAG",
|
|
||||||
office: offices[0],
|
|
||||||
private_description:
|
|
||||||
"Compte rendu écrit des discussions, décisions et résolutions prises lors d'une réunion d'assemblée générale de copropriété.",
|
|
||||||
public_description:
|
|
||||||
"Compte rendu écrit des discussions, décisions et résolutions prises lors d'une réunion d'assemblée générale de copropriété.",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
archived_at: null,
|
|
||||||
name: "Règlement de copropriété",
|
|
||||||
office: offices[0],
|
|
||||||
private_description:
|
|
||||||
"Document juridique qui établit les règles et les droits des copropriétaires d'un immeuble en copropriété.",
|
|
||||||
public_description: "Document juridique qui établit les règles et les droits des copropriétaires d'un immeuble en copropriété.",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
archived_at: null,
|
|
||||||
name: "Titre de propriété",
|
|
||||||
office: offices[0],
|
|
||||||
private_description: "Document légal qui atteste de la propriété d'un bien immobilier et en identifie le propriétaire.",
|
|
||||||
public_description: "Document légal qui atteste de la propriété d'un bien immobilier et en identifie le propriétaire.",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
archived_at: null,
|
|
||||||
name: "Plan et loi carrez",
|
|
||||||
office: offices[0],
|
|
||||||
private_description:
|
|
||||||
"Document officiel qui mesure la superficie d'un lot ou d'un bien immobilier, conformément à la loi Carrez qui encadre les transactions immobilières.",
|
|
||||||
public_description:
|
|
||||||
"Document officiel qui mesure la superficie d'un lot ou d'un bien immobilier, conformément à la loi Carrez qui encadre les transactions immobilières.",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
archived_at: null,
|
|
||||||
name: "CNI",
|
|
||||||
office: offices[0],
|
|
||||||
private_description:
|
|
||||||
"Document officiel d'identification délivré par l'État pour prouver l'identité et la nationalité d'une personne.",
|
|
||||||
public_description:
|
|
||||||
"Document officiel d'identification délivré par l'État pour prouver l'identité et la nationalité d'une personne.",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
archived_at: null,
|
|
||||||
name: "Modifications règlement copropriété (plusieurs)",
|
|
||||||
office: offices[0],
|
|
||||||
private_description:
|
|
||||||
"Documents légaux qui apportent des changements ou des ajustements aux règles et dispositions du règlement de copropriété initial.",
|
|
||||||
public_description:
|
|
||||||
"Documents légaux qui apportent des changements ou des ajustements aux règles et dispositions du règlement de copropriété initial.",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
archived_at: null,
|
|
||||||
name: "Avis de décès",
|
|
||||||
office: offices[0],
|
|
||||||
private_description: "Notification officielle délivrée par les autorités compétentes pour informer du décès d'une personne.",
|
|
||||||
public_description: "Notification officielle délivrée par les autorités compétentes pour informer du décès d'une personne.",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
archived_at: null,
|
|
||||||
name: "Lettre de mission",
|
|
||||||
office: offices[0],
|
|
||||||
private_description:
|
|
||||||
"Document contractuel qui définit les termes et les objectifs d'une mission confiée à une personne ou à une entreprise.",
|
|
||||||
public_description:
|
|
||||||
"Document contractuel qui définit les termes et les objectifs d'une mission confiée à une personne ou à une entreprise.",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
archived_at: null,
|
|
||||||
name: "DPE",
|
|
||||||
office: offices[0],
|
|
||||||
private_description: "Diagnostic de Performance Energétique.",
|
|
||||||
public_description: "Diagnostic de Performance Energétique.",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
archived_at: null,
|
|
||||||
name: "RIB",
|
|
||||||
office: offices[0],
|
|
||||||
private_description: "Relevé d'identité bancaire ou IBAN.",
|
|
||||||
public_description: "Relevé d'identité bancaire ou IBAN.",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
archived_at: null,
|
|
||||||
name: "Acte d'achat par la SCI",
|
|
||||||
office: offices[0],
|
|
||||||
private_description: "Acte d'achat par la SCI.",
|
|
||||||
public_description: "Acte d'achat par la SCI.",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
archived_at: null,
|
|
||||||
name: "Other",
|
|
||||||
office: offices[0],
|
|
||||||
private_description: "Other",
|
|
||||||
public_description: "Other",
|
|
||||||
created_at: new Date(),
|
|
||||||
updated_at: new Date(),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const officeFolders: OfficeFolder[] = [
|
const officeFolders: OfficeFolder[] = [
|
||||||
{
|
{
|
||||||
folder_number: "0001",
|
folder_number: "0001",
|
||||||
@ -1357,7 +1318,7 @@ export default async function main() {
|
|||||||
city: office.address!.city,
|
city: office.address!.city,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
office_status: EOfficeStatus.DESACTIVATED,
|
office_status: EOfficeStatus.ACTIVATED,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
office.uid = officeCreated.uid;
|
office.uid = officeCreated.uid;
|
||||||
@ -1496,6 +1457,22 @@ export default async function main() {
|
|||||||
customer.uid = customersCreated.uid;
|
customer.uid = customersCreated.uid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const documentType of documentTypes) {
|
||||||
|
const documentTypeCreated = await prisma.documentTypes.create({
|
||||||
|
data: {
|
||||||
|
name: documentType.name,
|
||||||
|
public_description: documentType.public_description,
|
||||||
|
private_description: documentType.private_description,
|
||||||
|
office: {
|
||||||
|
connect: {
|
||||||
|
uid: documentType.office!.uid,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
documentType.uid = documentTypeCreated.uid;
|
||||||
|
}
|
||||||
|
|
||||||
for (const deedType of deedTypes) {
|
for (const deedType of deedTypes) {
|
||||||
const createArgs: Prisma.DeedTypesCreateArgs = {
|
const createArgs: Prisma.DeedTypesCreateArgs = {
|
||||||
data: {
|
data: {
|
||||||
@ -1547,22 +1524,6 @@ export default async function main() {
|
|||||||
deed.uid = deedCreated.uid;
|
deed.uid = deedCreated.uid;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const documentType of documentTypes) {
|
|
||||||
const documentTypeCreated = await prisma.documentTypes.create({
|
|
||||||
data: {
|
|
||||||
name: documentType.name,
|
|
||||||
public_description: documentType.public_description,
|
|
||||||
private_description: documentType.private_description,
|
|
||||||
office: {
|
|
||||||
connect: {
|
|
||||||
uid: documentType.office!.uid,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
documentType.uid = documentTypeCreated.uid;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const officeFolder of officeFolders) {
|
for (const officeFolder of officeFolders) {
|
||||||
const officeFolderCreated = await prisma.officeFolders.create({
|
const officeFolderCreated = await prisma.officeFolders.create({
|
||||||
data: {
|
data: {
|
||||||
@ -1591,10 +1552,9 @@ export default async function main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
console.log(">MOCK DATA - Seeding completed!");
|
console.log(">MOCK DATA - Seeding completed!");
|
||||||
}
|
} catch (error) {
|
||||||
catch(error){
|
console.log(error);
|
||||||
console.log("Data already seeded, skiping");
|
console.log("Data already seeded, skiping");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
main();
|
main();
|
||||||
|
29
src/common/optics/notary/index.ts
Normal file
29
src/common/optics/notary/index.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import * as Optics from "monocle-ts";
|
||||||
|
import * as Traversal from "monocle-ts/Traversal";
|
||||||
|
import * as Array from "fp-ts/Array";
|
||||||
|
|
||||||
|
import { Document, File, OfficeFolder } from "le-coffre-resources/dist/Notary";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lenses
|
||||||
|
*/
|
||||||
|
export const folderDocumentsLens = Optics.Lens.fromNullableProp<OfficeFolder>()("documents", []);
|
||||||
|
export const documentFilesLens = Optics.Lens.fromNullableProp<Document>()("files", []);
|
||||||
|
export const fileHashLens = Optics.Lens.fromProp<File>()("hash");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Traversals
|
||||||
|
*/
|
||||||
|
export const documentsTraversal = Optics.fromTraversable(Array.Traversable)<Document>();
|
||||||
|
export const filesTraversal = Optics.fromTraversable(Array.Traversable)<File>();
|
||||||
|
|
||||||
|
export const folderHashesTraversal = folderDocumentsLens
|
||||||
|
.composeTraversal(documentsTraversal)
|
||||||
|
.composeLens(documentFilesLens)
|
||||||
|
.composeTraversal(filesTraversal)
|
||||||
|
.composeLens(fileHashLens);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getters
|
||||||
|
*/
|
||||||
|
export const getFolderHashes = (folder: OfficeFolder) => Traversal.getAll(folder)(folderHashesTraversal);
|
@ -38,6 +38,7 @@ export default class FilesRepository extends BaseRepository {
|
|||||||
file_name: file.file_name,
|
file_name: file.file_name,
|
||||||
file_path: file.file_path,
|
file_path: file.file_path,
|
||||||
mimetype: file.mimetype,
|
mimetype: file.mimetype,
|
||||||
|
hash: file.hash,
|
||||||
size: file.size,
|
size: file.size,
|
||||||
key: key,
|
key: key,
|
||||||
},
|
},
|
||||||
@ -57,6 +58,7 @@ export default class FilesRepository extends BaseRepository {
|
|||||||
file_name: file.file_name,
|
file_name: file.file_name,
|
||||||
file_path: file.file_path,
|
file_path: file.file_path,
|
||||||
mimetype: file.mimetype,
|
mimetype: file.mimetype,
|
||||||
|
hash: file.hash,
|
||||||
size: file.size,
|
size: file.size,
|
||||||
key: key,
|
key: key,
|
||||||
},
|
},
|
||||||
|
@ -72,6 +72,31 @@ export default class OfficesRepository extends BaseRepository {
|
|||||||
return this.model.update(updateArgs);
|
return this.model.update(updateArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : Update check date of an office
|
||||||
|
*/
|
||||||
|
public async updateCheckedAt(uid: string) {
|
||||||
|
return this.model.update({
|
||||||
|
where: {
|
||||||
|
uid: uid,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
checked_at: new Date(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : Delete an office
|
||||||
|
*/
|
||||||
|
public async delete(uid: string): Promise<Offices> {
|
||||||
|
return this.model.delete({
|
||||||
|
where: {
|
||||||
|
uid: uid,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description : Find one office
|
* @description : Find one office
|
||||||
*/
|
*/
|
||||||
@ -93,4 +118,25 @@ export default class OfficesRepository extends BaseRepository {
|
|||||||
include: query,
|
include: query,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : Find offices which need to be checked with idNot API
|
||||||
|
*/
|
||||||
|
public async findManyToCheck() {
|
||||||
|
return this.model.findMany({
|
||||||
|
where: {
|
||||||
|
OR: [
|
||||||
|
{
|
||||||
|
checked_at: null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
checked_at: { lt: new Date(Date.now() - 3 * 60 * 1000) }, // less than 24h ago
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
address: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -108,7 +108,7 @@ export default class UsersRepository extends BaseRepository {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if(user.office_membership) {
|
if (user.office_membership) {
|
||||||
updateArgs.data.office_membership = {
|
updateArgs.data.office_membership = {
|
||||||
connect: {
|
connect: {
|
||||||
idNot: user.office_membership?.idNot,
|
idNot: user.office_membership?.idNot,
|
||||||
@ -124,7 +124,7 @@ export default class UsersRepository extends BaseRepository {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if(user.office_role) {
|
if (user.office_role) {
|
||||||
updateArgs.data.office_role = {
|
updateArgs.data.office_role = {
|
||||||
connect: {
|
connect: {
|
||||||
uid: user.office_role.uid,
|
uid: user.office_role.uid,
|
||||||
@ -132,7 +132,7 @@ export default class UsersRepository extends BaseRepository {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if(user.role) {
|
if (user.role) {
|
||||||
updateArgs.data.role = {
|
updateArgs.data.role = {
|
||||||
connect: {
|
connect: {
|
||||||
uid: user.role.uid,
|
uid: user.role.uid,
|
||||||
@ -144,17 +144,31 @@ export default class UsersRepository extends BaseRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description : Update role from a user
|
* @description : Update check date of a user
|
||||||
*/
|
*/
|
||||||
public async updateRole(uid: string, user: User): Promise<Users> {
|
public async updateCheckedAt(uid: string) {
|
||||||
|
return this.model.update({
|
||||||
|
where: {
|
||||||
|
uid: uid,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
checked_at: new Date(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : Update office role from a user
|
||||||
|
*/
|
||||||
|
public async updateOfficeRole(uid: string, user: User): Promise<Users> {
|
||||||
const updateArgs: Prisma.UsersUpdateArgs = {
|
const updateArgs: Prisma.UsersUpdateArgs = {
|
||||||
where: {
|
where: {
|
||||||
uid: uid,
|
uid: uid,
|
||||||
},
|
},
|
||||||
data: {}
|
data: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
if(user.office_role) {
|
if (user.office_role) {
|
||||||
updateArgs.data.office_role = {
|
updateArgs.data.office_role = {
|
||||||
connect: {
|
connect: {
|
||||||
uid: user.office_role.uid,
|
uid: user.office_role.uid,
|
||||||
@ -162,17 +176,20 @@ export default class UsersRepository extends BaseRepository {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if(user.role) {
|
|
||||||
updateArgs.data.role = {
|
|
||||||
connect: {
|
|
||||||
uid: user.role.uid,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.model.update({ ...updateArgs, include: { contact: true, office_membership: { include: { address: true } } } });
|
return this.model.update({ ...updateArgs, include: { contact: true, office_membership: { include: { address: true } } } });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : Delete one user
|
||||||
|
*/
|
||||||
|
public async delete(uid: string): Promise<Users> {
|
||||||
|
return this.model.delete({
|
||||||
|
where: {
|
||||||
|
uid: uid,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description : Find one user
|
* @description : Find one user
|
||||||
*/
|
*/
|
||||||
@ -200,7 +217,7 @@ export default class UsersRepository extends BaseRepository {
|
|||||||
/**
|
/**
|
||||||
* @description : Find one user with office
|
* @description : Find one user with office
|
||||||
*/
|
*/
|
||||||
public async findOneByUidWithRole(uid: string): Promise<((Users & {role: Role} )| null)> {
|
public async findOneByUidWithRole(uid: string): Promise<(Users & { role: Role }) | null> {
|
||||||
return this.model.findUnique({
|
return this.model.findUnique({
|
||||||
where: {
|
where: {
|
||||||
uid: uid,
|
uid: uid,
|
||||||
@ -222,4 +239,27 @@ export default class UsersRepository extends BaseRepository {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : Find users which need to be checked with idNot API
|
||||||
|
*/
|
||||||
|
public async findManyToCheck() {
|
||||||
|
return this.model.findMany({
|
||||||
|
where: {
|
||||||
|
OR: [
|
||||||
|
{
|
||||||
|
checked_at: null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
checked_at: { lt: new Date(Date.now() - 3 * 60 * 1000) }, // less than 24h ago
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
contact: true,
|
||||||
|
role: true,
|
||||||
|
office_membership: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,9 @@ import CronService from "@Services/common/CronService/CronService";
|
|||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
const variables = await Container.get(BackendVariables).validate();
|
const variables = await Container.get(BackendVariables).validate();
|
||||||
if(variables.ENV === "stg"){
|
Container.get(CronService).archiveFiles();
|
||||||
|
await Container.get(CronService).updateUsers();
|
||||||
|
if(variables.ENV !== "dev"){
|
||||||
Container.get(CronService).sendMails();
|
Container.get(CronService).sendMails();
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -19,20 +19,12 @@ export default class UsersService extends BaseService {
|
|||||||
return this.userRepository.findMany(query);
|
return this.userRepository.findMany(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @description : Create a user
|
|
||||||
* @throws {Error} If user couldn't be created
|
|
||||||
*/
|
|
||||||
public create(userEntity: User): Promise<Users> {
|
|
||||||
return this.userRepository.create(userEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description : Modify a user
|
* @description : Modify a user
|
||||||
* @throws {Error} If user modification failed
|
* @throws {Error} If user modification failed
|
||||||
*/
|
*/
|
||||||
public async update(uid: string, userEntity: User): Promise<Users> {
|
public async update(uid: string, userEntity: User): Promise<Users> {
|
||||||
return this.userRepository.updateRole(uid, userEntity);
|
return this.userRepository.updateOfficeRole(uid, userEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,6 +16,11 @@ interface ICustomerJwtPayload {
|
|||||||
email: string;
|
email: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IdNotJwtPayload {
|
||||||
|
sub: string,
|
||||||
|
profile_idn: string,
|
||||||
|
entity_idn: string,
|
||||||
|
}
|
||||||
|
|
||||||
interface IUserJwtPayload {
|
interface IUserJwtPayload {
|
||||||
userId: string;
|
userId: string;
|
||||||
@ -79,7 +84,7 @@ export default class AuthService extends BaseService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
public generateAccessToken(user: any): string {
|
public generateAccessToken(user: any): string {
|
||||||
return jwt.sign({ ...user }, this.variables.ACCESS_TOKEN_SECRET, { expiresIn: "1h" });
|
return jwt.sign({ ...user }, this.variables.ACCESS_TOKEN_SECRET, { expiresIn: "15m" });
|
||||||
}
|
}
|
||||||
|
|
||||||
public generateRefreshToken(user: any): string {
|
public generateRefreshToken(user: any): string {
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
import { Service } from "typedi";
|
import { Service } from "typedi";
|
||||||
import { CronJob } from "cron";
|
import { CronJob } from "cron";
|
||||||
import MailchimpService from "../MailchimpService/MailchimpService";
|
import MailchimpService from "../MailchimpService/MailchimpService";
|
||||||
|
import FilesService from "../FilesService/FilesService";
|
||||||
|
import IdNotService from "../IdNotService/IdNotService";
|
||||||
|
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class CronService {
|
export default class CronService {
|
||||||
constructor(private mailchimpService: MailchimpService) {}
|
constructor(private mailchimpService: MailchimpService, private filesService: FilesService, private idNotService: IdNotService) {}
|
||||||
|
|
||||||
public async sendMails() {
|
public async sendMails() {
|
||||||
const cronJob = new CronJob("*/15 * * * * *", async () => {
|
const cronJob = new CronJob("*/15 * * * *", async () => { // Every 15 minutes
|
||||||
try {
|
try {
|
||||||
await this.mailchimpService.sendEmails();
|
await this.mailchimpService.sendEmails();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -21,4 +23,33 @@ export default class CronService {
|
|||||||
cronJob.start();
|
cronJob.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async archiveFiles() {
|
||||||
|
const cronJob = new CronJob("0 0 * * MON", async () => { // Every monday at midnight
|
||||||
|
try {
|
||||||
|
await this.filesService.archiveOldFiles();
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Start job
|
||||||
|
if (!cronJob.running) {
|
||||||
|
cronJob.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public async updateUsers() {
|
||||||
|
const cronJob = new CronJob("0 0 * * *", async () => { // Once a day at midnight
|
||||||
|
try {
|
||||||
|
await this.idNotService.updateOffices();
|
||||||
|
await this.idNotService.updateUsers();
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Start job
|
||||||
|
if (!cronJob.running) {
|
||||||
|
cronJob.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,10 @@ export default class CryptoService extends BaseService {
|
|||||||
return crypto.createHash("sha256").update(String(key)).digest("base64").slice(0, 32);
|
return crypto.createHash("sha256").update(String(key)).digest("base64").slice(0, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async getHash(buffer: Buffer): Promise<string> {
|
||||||
|
return crypto.createHash("sha256").update(buffer).digest("hex");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description : encrypt data
|
* @description : encrypt data
|
||||||
* @throws {Error} If data cannot be encrypted
|
* @throws {Error} If data cannot be encrypted
|
||||||
|
@ -71,12 +71,15 @@ export default class FilesService extends BaseService {
|
|||||||
public async create(file: File, fileData: Express.Multer.File) {
|
public async create(file: File, fileData: Express.Multer.File) {
|
||||||
const key = v4();
|
const key = v4();
|
||||||
const encryptedFile = await this.cryptoService.encrypt(fileData.buffer, key);
|
const encryptedFile = await this.cryptoService.encrypt(fileData.buffer, key);
|
||||||
|
const hash = await this.cryptoService.getHash(fileData.buffer);
|
||||||
|
|
||||||
const upload = await this.ipfsService.pinFile(Readable.from(encryptedFile), fileData.originalname);
|
const upload = await this.ipfsService.pinFile(Readable.from(encryptedFile), fileData.originalname);
|
||||||
let fileToCreate: File = file;
|
let fileToCreate: File = file;
|
||||||
fileToCreate.file_name = fileData.originalname;
|
fileToCreate.file_name = fileData.originalname;
|
||||||
fileToCreate.file_path = this.variables.PINATA_GATEWAY.concat(upload.IpfsHash);
|
fileToCreate.file_path = this.variables.PINATA_GATEWAY.concat(upload.IpfsHash);
|
||||||
fileToCreate.mimetype = fileData.mimetype;
|
fileToCreate.mimetype = fileData.mimetype;
|
||||||
fileToCreate.size = fileData.size;
|
fileToCreate.size = fileData.size;
|
||||||
|
fileToCreate.hash = hash;
|
||||||
fileToCreate.archived_at = null;
|
fileToCreate.archived_at = null;
|
||||||
|
|
||||||
return this.filesRepository.create(fileToCreate, key);
|
return this.filesRepository.create(fileToCreate, key);
|
||||||
@ -107,4 +110,32 @@ export default class FilesService extends BaseService {
|
|||||||
|
|
||||||
return this.filesRepository.deleteKeyAndArchive(uid);
|
return this.filesRepository.deleteKeyAndArchive(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : find files to be archived
|
||||||
|
* @throws {Error} If file key cannot be deleted or archived
|
||||||
|
*/
|
||||||
|
public async getFilesToBeArchived() {
|
||||||
|
return this.filesRepository.findMany({
|
||||||
|
where: {
|
||||||
|
archived_at: null,
|
||||||
|
created_at: { lt: new Date(Date.now() - 1000 * 60 * 60 * 24 * 30 * 3) }, // 90 days
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : find files to be archived
|
||||||
|
* @throws {Error} If file key cannot be deleted or archived
|
||||||
|
*/
|
||||||
|
public async archiveOldFiles() {
|
||||||
|
const files = await this.getFilesToBeArchived();
|
||||||
|
files.forEach(async (file) => {
|
||||||
|
try {
|
||||||
|
await this.deleteKeyAndArchive(file.uid);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
371
src/services/common/IdNotService/IdNotService.ts
Normal file
371
src/services/common/IdNotService/IdNotService.ts
Normal file
@ -0,0 +1,371 @@
|
|||||||
|
import BaseService from "@Services/BaseService";
|
||||||
|
import { BackendVariables } from "@Common/config/variables/Variables";
|
||||||
|
import { Service } from "typedi";
|
||||||
|
import jwt from "jsonwebtoken";
|
||||||
|
import UsersService from "@Services/super-admin/UsersService/UsersService";
|
||||||
|
import { IdNotJwtPayload } from "../AuthService/AuthService";
|
||||||
|
import User, { Office, Role } from "le-coffre-resources/dist/SuperAdmin";
|
||||||
|
import RolesService from "@Services/super-admin/RolesService/RolesService";
|
||||||
|
import OfficesService from "@Services/super-admin/OfficesService/OfficesService";
|
||||||
|
import { EOfficeStatus } from "@prisma/client";
|
||||||
|
|
||||||
|
interface IIdNotToken {
|
||||||
|
access_token: string;
|
||||||
|
expires_in: number;
|
||||||
|
id_token: string;
|
||||||
|
token_type: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IRattachementData {
|
||||||
|
entiteUrl: string;
|
||||||
|
personneUrl: string;
|
||||||
|
entite: {
|
||||||
|
codeCrpcen: string;
|
||||||
|
typeEntite: {
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
|
ou: string;
|
||||||
|
denominationSociale: string;
|
||||||
|
statutEntite: {
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
|
locationsUrl: string;
|
||||||
|
}
|
||||||
|
personne: {
|
||||||
|
numeroTelephonePro: string;
|
||||||
|
prenom: string;
|
||||||
|
nomUsuel: string;
|
||||||
|
mobilePro: string;
|
||||||
|
numeroAdherentCrpcen: string;
|
||||||
|
civilite: string;
|
||||||
|
};
|
||||||
|
typeLien: {
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
|
numeroMobile: string;
|
||||||
|
numeroTelephone: string;
|
||||||
|
statutDuRattachement: boolean;
|
||||||
|
mailRattachement: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IOfficeData {
|
||||||
|
ou: string;
|
||||||
|
intitule: string;
|
||||||
|
denominationSociale: string;
|
||||||
|
departementResidence: {
|
||||||
|
libelle: string;
|
||||||
|
code: string;
|
||||||
|
}[];
|
||||||
|
libelle: string;
|
||||||
|
codeCrpcen: string;
|
||||||
|
locationsUrl: string;
|
||||||
|
statutEntite: {
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
|
typeEntite: {
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IOfficeLocation {
|
||||||
|
totalResultCount: number;
|
||||||
|
page: number;
|
||||||
|
size: number;
|
||||||
|
result: {
|
||||||
|
mail: string;
|
||||||
|
numeroTelephone: string;
|
||||||
|
adrGeo4: string;
|
||||||
|
adrGeoCodePostal: string;
|
||||||
|
adrGeoVille: string;
|
||||||
|
ou: string;
|
||||||
|
lastModified: string;
|
||||||
|
deleted: boolean;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
|
||||||
|
enum EIdnotRole {
|
||||||
|
DIRECTEUR = "Directeur général du CSN",
|
||||||
|
NOTAIRE_TITULAIRE = "Notaire titulaire",
|
||||||
|
NOTAIRE_ASSOCIE = "Notaire associé",
|
||||||
|
NOTAIRE_SALARIE = "Notaire salarié",
|
||||||
|
COLLABORATEUR = "Collaborateur",
|
||||||
|
SECRETAIRE_GENERAL = "Secrétaire général",
|
||||||
|
SUPPLEANT = "Suppléant",
|
||||||
|
ADMINISTRATEUR = "Administrateur",
|
||||||
|
RESPONSABLE = "Responsable",
|
||||||
|
}
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export default class IdNotService extends BaseService {
|
||||||
|
constructor(
|
||||||
|
protected variables: BackendVariables,
|
||||||
|
private userService: UsersService,
|
||||||
|
private officeService: OfficesService,
|
||||||
|
private rolesService: RolesService,
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getIdNotToken(code: string) {
|
||||||
|
const query = new URLSearchParams({
|
||||||
|
client_id: this.variables.IDNOT_CLIENT_ID,
|
||||||
|
client_secret: this.variables.IDNOT_CLIENT_SECRET,
|
||||||
|
redirect_uri: `${this.variables.APP_HOST}/authorized-client`,
|
||||||
|
code: code,
|
||||||
|
grant_type: "authorization_code",
|
||||||
|
});
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getRole(roleName: string): Promise<Role> {
|
||||||
|
switch (roleName) {
|
||||||
|
case EIdnotRole.DIRECTEUR:
|
||||||
|
return (await this.rolesService.get({ where: { name: "admin" } }))[0]!;
|
||||||
|
case EIdnotRole.NOTAIRE_TITULAIRE:
|
||||||
|
return (await this.rolesService.get({ where: { name: "notary" } }))[0]!;
|
||||||
|
case EIdnotRole.NOTAIRE_ASSOCIE:
|
||||||
|
return (await this.rolesService.get({ where: { name: "notary" } }))[0]!;
|
||||||
|
case EIdnotRole.NOTAIRE_SALARIE:
|
||||||
|
return (await this.rolesService.get({ where: { name: "notary" } }))[0]!;
|
||||||
|
case EIdnotRole.COLLABORATEUR:
|
||||||
|
return (await this.rolesService.get({ where: { name: "collaborator" } }))[0]!;
|
||||||
|
case EIdnotRole.SECRETAIRE_GENERAL:
|
||||||
|
return (await this.rolesService.get({ where: { name: "notary" } }))[0]!;
|
||||||
|
case EIdnotRole.SUPPLEANT:
|
||||||
|
return (await this.rolesService.get({ where: { name: "notary" } }))[0]!;
|
||||||
|
case EIdnotRole.ADMINISTRATEUR:
|
||||||
|
return (await this.rolesService.get({ where: { name: "admin" } }))[0]!;
|
||||||
|
case EIdnotRole.RESPONSABLE:
|
||||||
|
return (await this.rolesService.get({ where: { name: "collaborator" } }))[0]!;
|
||||||
|
default:
|
||||||
|
return (await this.rolesService.get({ where: { name: "default" } }))[0]!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public getOfficeStatus(statusName: string) {
|
||||||
|
switch (statusName) {
|
||||||
|
case "Pourvu":
|
||||||
|
return EOfficeStatus.ACTIVATED;
|
||||||
|
case "Pourvu mais décédé":
|
||||||
|
return EOfficeStatus.ACTIVATED;
|
||||||
|
case "Sans titulaire":
|
||||||
|
return EOfficeStatus.ACTIVATED;
|
||||||
|
case "Vacance":
|
||||||
|
return EOfficeStatus.ACTIVATED;
|
||||||
|
case "En activité":
|
||||||
|
return EOfficeStatus.ACTIVATED;
|
||||||
|
default:
|
||||||
|
return EOfficeStatus.DESACTIVATED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async updateUser(userId: string) {
|
||||||
|
const userInfos = await this.userService.getByUid(userId, { contact: true, role: true, office_membership: true });
|
||||||
|
const user = User.hydrate<User>(userInfos!);
|
||||||
|
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?` +
|
||||||
|
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;
|
||||||
|
rattachementsResults.forEach(async (rattachement) => {
|
||||||
|
if (rattachement.statutDuRattachement) {
|
||||||
|
const officeData = await (await fetch(
|
||||||
|
`${this.variables.IDNOT_API_BASE_URL + rattachement.entiteUrl}?` +
|
||||||
|
searchParams,
|
||||||
|
{
|
||||||
|
method: "GET",
|
||||||
|
},
|
||||||
|
)).json() as IOfficeData;
|
||||||
|
if(officeData.typeEntite.name === "office") {
|
||||||
|
userData = rattachement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const roleFromIdNot = await this.getRole(userData.typeLien.name);
|
||||||
|
let updates = 0;
|
||||||
|
|
||||||
|
if (user.role!.uid !== roleFromIdNot.uid) {
|
||||||
|
updates++;
|
||||||
|
user.role = roleFromIdNot;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user.office_membership!.idNot !== userData.entite.ou) {
|
||||||
|
updates++;
|
||||||
|
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" })
|
||||||
|
).json()) as IOfficeLocation;
|
||||||
|
const office = {
|
||||||
|
idNot: userData.entite.ou,
|
||||||
|
name: userData.entite.denominationSociale,
|
||||||
|
crpcen: userData.entite.codeCrpcen,
|
||||||
|
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,
|
||||||
|
zip_code: Number(officeLocationData.result[0]!.adrGeoCodePostal),
|
||||||
|
created_at: null,
|
||||||
|
updated_at: null,
|
||||||
|
},
|
||||||
|
created_at: null,
|
||||||
|
updated_at: null,
|
||||||
|
};
|
||||||
|
officeData = await this.officeService.create(office);
|
||||||
|
}
|
||||||
|
user.office_membership = officeData;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user.contact!.email !== userData.mailRattachement) {
|
||||||
|
updates++;
|
||||||
|
user.contact!.email = userData.mailRattachement;
|
||||||
|
}
|
||||||
|
if (user.contact!.cell_phone_number !== userData.numeroMobile) {
|
||||||
|
updates++;
|
||||||
|
user.contact!.cell_phone_number = userData.numeroMobile;
|
||||||
|
}
|
||||||
|
if (updates != 0) await this.userService.update(user.uid!, user);
|
||||||
|
await this.userService.updateCheckedAt(user.uid!);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async updateOffice(officeId: string) {
|
||||||
|
const officeInfos = await this.officeService.getByUid(officeId);
|
||||||
|
console.log(officeInfos)
|
||||||
|
const office = Office.hydrate<Office>(officeInfos!);
|
||||||
|
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",
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (officeRawData.status === 404) {
|
||||||
|
await this.officeService.updateCheckedAt(office.uid!);
|
||||||
|
//await this.officeService.delete(office.uid!);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const officeData = (await officeRawData.json()) as IOfficeData;
|
||||||
|
console.log(officeData);
|
||||||
|
let updates = 0;
|
||||||
|
if(office.name !== officeData.denominationSociale) {
|
||||||
|
updates++;
|
||||||
|
office.name = officeData.denominationSociale;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
await this.officeService.updateCheckedAt(office.uid!);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getOrCreateUser(decodedToken: IdNotJwtPayload) {
|
||||||
|
let user = await this.userService.getByProvider("idNot", decodedToken.sub);
|
||||||
|
if (!user) {
|
||||||
|
const searchParams = new URLSearchParams({
|
||||||
|
key: this.variables.IDNOT_API_KEY,
|
||||||
|
});
|
||||||
|
|
||||||
|
const userData = (await (
|
||||||
|
await fetch(`${this.variables.IDNOT_API_BASE_URL}/api/pp/v2/rattachements/${decodedToken.profile_idn}?` + searchParams, {
|
||||||
|
method: "GET",
|
||||||
|
})
|
||||||
|
).json()) as IRattachementData;
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
// if(officeLocationData.result[0]!.adrGeoCodePostal.slice(0,2) !== "35") {
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
|
||||||
|
const role = await this.getRole(userData.typeLien.name);
|
||||||
|
|
||||||
|
const userToAdd = {
|
||||||
|
idNot: decodedToken.sub,
|
||||||
|
office_membership: {
|
||||||
|
idNot: decodedToken.entity_idn,
|
||||||
|
name: userData.entite.denominationSociale,
|
||||||
|
crpcen: userData.entite.codeCrpcen,
|
||||||
|
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,
|
||||||
|
zip_code: Number(officeLocationData.result[0]!.adrGeoCodePostal),
|
||||||
|
created_at: null,
|
||||||
|
updated_at: null,
|
||||||
|
},
|
||||||
|
created_at: null,
|
||||||
|
updated_at: null,
|
||||||
|
},
|
||||||
|
role: role,
|
||||||
|
contact: {
|
||||||
|
first_name: userData.personne.prenom,
|
||||||
|
last_name: userData.personne.nomUsuel,
|
||||||
|
email: userData.mailRattachement,
|
||||||
|
phone_number: userData.numeroTelephone,
|
||||||
|
cell_phone_number: userData.numeroMobile ?? userData.numeroTelephone,
|
||||||
|
civility: userData.personne.civilite,
|
||||||
|
created_at: null,
|
||||||
|
updated_at: null,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const userToHydrate = User.hydrate<User>(userToAdd);
|
||||||
|
return await this.userService.create(userToHydrate);
|
||||||
|
}
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async updateUsers() {
|
||||||
|
const usersReq = await this.userService.getUsersToBeChecked();
|
||||||
|
const users = User.hydrateArray<User>(usersReq);
|
||||||
|
users.forEach(async (user) => {
|
||||||
|
await this.updateUser(user.uid!);
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public async updateOffices() {
|
||||||
|
const officesReq = await this.officeService.getOfficesToBeChecked();
|
||||||
|
const offices = Office.hydrateArray<Office>(officesReq);
|
||||||
|
offices.forEach(async (office) => {
|
||||||
|
await this.updateOffice(office.uid!);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
59
src/services/common/SecureService/SecureService.ts
Normal file
59
src/services/common/SecureService/SecureService.ts
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import BaseService from "@Services/BaseService";
|
||||||
|
import { Service } from "typedi";
|
||||||
|
import { BackendVariables } from "@Common/config/variables/Variables";
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export default class SecureService extends BaseService {
|
||||||
|
constructor(protected variables: BackendVariables) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : anchor a sequence of hashes
|
||||||
|
* @throws {Error} If secure job cannot be created
|
||||||
|
*/
|
||||||
|
public async anchor(hash_sources: string[]) {
|
||||||
|
const url = new URL(this.variables.SECURE_API_BASE_URL.concat("/flows/v2/anchor"));
|
||||||
|
|
||||||
|
const response = await fetch(url, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Accept: "application/json",
|
||||||
|
apiKey: this.variables.SECURE_API_KEY,
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
hash_sources,
|
||||||
|
callback_url: "",
|
||||||
|
callback_config: {},
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
return await response.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : verify if a sequence of hashes is anchored
|
||||||
|
* @throws {Error} If secure job cannot be found
|
||||||
|
*/
|
||||||
|
public async verify(hash_sources: string[]) {
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
|
||||||
|
hash_sources.forEach((hash) => {
|
||||||
|
params.append("hash_sources", hash);
|
||||||
|
});
|
||||||
|
|
||||||
|
const url = new URL(this.variables.SECURE_API_BASE_URL.concat("/flows/v2/verify?").concat(params.toString()));
|
||||||
|
|
||||||
|
const response = await fetch(url, {
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Accept: "application/json",
|
||||||
|
apiKey: this.variables.SECURE_API_KEY,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return await response.json();
|
||||||
|
}
|
||||||
|
}
|
@ -34,6 +34,23 @@ export default class OfficesService extends BaseService {
|
|||||||
return this.officeRepository.update(uid, officeEntity);
|
return this.officeRepository.update(uid, officeEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : Modify an office check date
|
||||||
|
* @throws {Error} If user modification failed
|
||||||
|
* @deprecate
|
||||||
|
*/
|
||||||
|
public updateCheckedAt(uid: string): Promise<Offices> {
|
||||||
|
return this.officeRepository.updateCheckedAt(uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : delete an office
|
||||||
|
* @throws {Error} If office cannot be modified
|
||||||
|
*/
|
||||||
|
public async delete(uid: string): Promise<Offices> {
|
||||||
|
return this.officeRepository.delete(uid);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description : Get a office by uid
|
* @description : Get a office by uid
|
||||||
* @throws {Error} If office cannot be get
|
* @throws {Error} If office cannot be get
|
||||||
@ -41,4 +58,11 @@ export default class OfficesService extends BaseService {
|
|||||||
public async getByUid(uid: string, query?: any): Promise<Offices | null> {
|
public async getByUid(uid: string, query?: any): Promise<Offices | null> {
|
||||||
return this.officeRepository.findOneByUid(uid, query);
|
return this.officeRepository.findOneByUid(uid, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : Get users to be checked with IdNot API
|
||||||
|
*/
|
||||||
|
public getOfficesToBeChecked() {
|
||||||
|
return this.officeRepository.findManyToCheck();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,23 @@ export default class UsersService extends BaseService {
|
|||||||
return this.userRepository.update(uid, userEntity);
|
return this.userRepository.update(uid, userEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : Modify a user check date
|
||||||
|
* @throws {Error} If user modification failed
|
||||||
|
* @deprecate
|
||||||
|
*/
|
||||||
|
public updateCheckedAt(uid: string): Promise<Users> {
|
||||||
|
return this.userRepository.updateCheckedAt(uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : Delete a user
|
||||||
|
* @throws {Error} If user modification failed
|
||||||
|
*/
|
||||||
|
public delete(uid: string): Promise<Users> {
|
||||||
|
return this.userRepository.delete(uid);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description : Get a user by uid
|
* @description : Get a user by uid
|
||||||
* @throws {Error} If user cannot be get by uid
|
* @throws {Error} If user cannot be get by uid
|
||||||
@ -66,4 +83,12 @@ export default class UsersService extends BaseService {
|
|||||||
public getByProvider(providerName: string, id: string) {
|
public getByProvider(providerName: string, id: string) {
|
||||||
return this.userRepository.findOneByProvider(providerName, id);
|
return this.userRepository.findOneByProvider(providerName, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : Get users to be checked with IdNot API
|
||||||
|
*/
|
||||||
|
public getUsersToBeChecked() {
|
||||||
|
return this.userRepository.findManyToCheck();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user