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", }); console.log(query) const token = await fetch(this.variables.IDNOT_BASE_URL + this.variables.IDNOT_CONNEXION_URL + "?" + query, { method: "POST" }); const decodedToken = (await token.json()) as IIdNotToken; console.log(decodedToken) const decodedIdToken = jwt.decode(decodedToken.id_token) as IdNotJwtPayload; return decodedIdToken; } public async getRole(roleName: string): Promise { 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(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(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(userToAdd); return await this.userService.create(userToHydrate); } return user; } public async updateUsers() { const usersReq = await this.userService.getUsersToBeChecked(); const users = User.hydrateArray(usersReq); users.forEach(async (user) => { await this.updateUser(user.uid!); }); } public async updateOffices() { const officesReq = await this.officeService.getOfficesToBeChecked(); const offices = Office.hydrateArray(officesReq); offices.forEach(async (office) => { await this.updateOffice(office.uid!); }); } }