Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Lbac 1490: revue du 26/04/24 #1212

Merged
merged 10 commits into from
Apr 30, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Boom from "boom"
import { assertUnreachable, toPublicUser, zRoutes } from "shared"
import { BusinessErrorCodes } from "shared/constants/errorCodes"
import { RECRUITER_STATUS } from "shared/constants/recruteur"
import { AccessStatus } from "shared/models/roleManagement.model"
import { UserEventType } from "shared/models/user2.model"
import { getLastStatusEvent } from "shared/utils/getLastStatusEvent"

Expand All @@ -20,7 +21,7 @@ import {
sendUserConfirmationEmail,
validateCreationEntrepriseFromCfa,
} from "@/services/etablissement.service"
import { getPublicUserRecruteurPropsOrError } from "@/services/roleManagement.service"
import { getMainRoleManagement, getPublicUserRecruteurPropsOrError } from "@/services/roleManagement.service"
import { getUser2ByEmail, validateUser2Email } from "@/services/user2.service"
import {
autoValidateUser,
Expand Down Expand Up @@ -196,14 +197,14 @@ export default (server: Server) => {
// Validation manuelle de l'utilisateur à effectuer pas un administrateur
await setUserHasToBeManuallyValidated(creationResult, origin, "pas d'email de contact")
await notifyToSlack(slackNotification)
return res.status(200).send({ user: userCfa })
return res.status(200).send({ user: userCfa, validated: false })
}
if (isUserMailExistInReferentiel(contacts, email)) {
// Validation automatique de l'utilisateur
await autoValidateUser(creationResult, origin, "l'email correspond à un contact")
await sendUserConfirmationEmail(userCfa)
// Keep the same structure as ENTREPRISE
return res.status(200).send({ user: userCfa })
return res.status(200).send({ user: userCfa, validated: true })
}
if (isEmailFromPrivateCompany(formatedEmail)) {
const domains = getAllDomainsFromEmailList(contacts.map(({ email }) => email))
Expand All @@ -213,14 +214,14 @@ export default (server: Server) => {
await autoValidateUser(creationResult, origin, "le nom de domaine de l'email correspond à celui d'un contact")
await sendUserConfirmationEmail(userCfa)
// Keep the same structure as ENTREPRISE
return res.status(200).send({ user: userCfa })
return res.status(200).send({ user: userCfa, validated: true })
}
}
// Validation manuelle de l'utilisateur à effectuer pas un administrateur
await setUserHasToBeManuallyValidated(creationResult, origin, "pas de validation automatique possible")
await notifyToSlack(slackNotification)
// Keep the same structure as ENTREPRISE
return res.status(200).send({ user: userCfa })
return res.status(200).send({ user: userCfa, validated: false })
}
default: {
assertUnreachable(type)
Expand Down Expand Up @@ -285,6 +286,9 @@ export default (server: Server) => {
}
if (!isUserEmailChecked(user)) {
await validateUser2Email(user._id.toString())
}
const mainRole = await getMainRoleManagement(user._id, true)
if (getLastStatusEvent(mainRole?.status)?.status === AccessStatus.GRANTED) {
await sendWelcomeEmailToUserRecruteur(user)
}

Expand Down
18 changes: 1 addition & 17 deletions server/src/http/controllers/jobs.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import {
import { getFtJobFromId } from "../../services/ftjob.service"
import { getJobsQuery } from "../../services/jobOpportunity.service"
import { getCompanyFromSiret } from "../../services/lbacompany.service"
import { addOffreDetailView, getLbaJobById, incrementLbaJobsViewCount } from "../../services/lbajob.service"
import { addOffreDetailView, getLbaJobById } from "../../services/lbajob.service"
import { getFicheMetierRomeV3FromDB } from "../../services/rome.service"
import { Server } from "../server"

Expand Down Expand Up @@ -353,14 +353,6 @@ export default (server: Server) => {
if ("error" in result) {
return res.status(500).send(result)
}

if ("matchas" in result && result.matchas) {
const { matchas } = result
if ("results" in matchas) {
await incrementLbaJobsViewCount(matchas.results.flatMap((job) => (job.job?.id ? [job.job.id] : [])))
}
}

return res.status(200).send(result)
}
)
Expand All @@ -378,14 +370,6 @@ export default (server: Server) => {
if ("error" in result) {
return res.status(500).send(result)
}

if ("matchas" in result && result.matchas) {
const { matchas } = result
if ("results" in matchas) {
await incrementLbaJobsViewCount(matchas.results.flatMap((job) => (job.job?.id ? [job.job.id] : [])))
}
}

return res.status(200).send(result)
}
)
Expand Down
20 changes: 2 additions & 18 deletions server/src/http/controllers/jobs.controller.v2.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Boom from "boom"
import { IJob, ILbaItemLbaJob, ILbaItemFtJob, JOB_STATUS, assertUnreachable, zRoutes } from "shared"
import { IJob, ILbaItemFtJob, ILbaItemLbaJob, JOB_STATUS, assertUnreachable, zRoutes } from "shared"
import { LBA_ITEM_TYPE } from "shared/constants/lbaitem"

import { getUserFromRequest } from "@/security/authenticationService"
Expand All @@ -26,7 +26,7 @@ import {
import { getFtJobFromIdV2 } from "../../services/ftjob.service"
import { getJobsQuery } from "../../services/jobOpportunity.service"
import { getCompanyFromSiret } from "../../services/lbacompany.service"
import { addOffreDetailView, getLbaJobByIdV2, incrementLbaJobsViewCount } from "../../services/lbajob.service"
import { addOffreDetailView, getLbaJobByIdV2 } from "../../services/lbajob.service"
import { getFicheMetierRomeV3FromDB } from "../../services/rome.service"
import { Server } from "../server"

Expand Down Expand Up @@ -348,14 +348,6 @@ export default (server: Server) => {
if ("error" in result) {
return res.status(500).send(result)
}

if ("matchas" in result && result.matchas) {
const { matchas } = result
if ("results" in matchas) {
await incrementLbaJobsViewCount(matchas.results.flatMap((job) => (job.job?.id ? [job.job.id] : [])))
}
}

return res.status(200).send(result)
}
)
Expand All @@ -374,14 +366,6 @@ export default (server: Server) => {
if ("error" in result) {
return res.status(500).send(result)
}

if ("matchas" in result && result.matchas) {
const { matchas } = result
if ("results" in matchas) {
await incrementLbaJobsViewCount(matchas.results.flatMap((job) => (job.job?.id ? [job.job.id] : [])))
}
}

return res.status(200).send(result)
}
)
Expand Down
4 changes: 2 additions & 2 deletions server/src/http/controllers/user.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,6 @@ export default (server: Server) => {
const opcoOrAdminRole = await RoleManagement.findOne({
user_id: requestUser._id,
authorized_type: { $in: [AccessEntityType.ADMIN, AccessEntityType.OPCO] },
$expr: { $eq: [{ $arrayElemAt: ["$status.status", -1] }, AccessStatus.GRANTED] },
}).lean()
if (opcoOrAdminRole && getLastStatusEvent(opcoOrAdminRole.status)?.status === AccessStatus.GRANTED) {
const userIds = userRecruteur.status.flatMap(({ user }) => (user ? [user] : []))
Expand Down Expand Up @@ -268,6 +267,7 @@ export default (server: Server) => {
onRequest: [server.auth(zRoutes.put["/user/:userId/organization/:organizationId/permission"])],
},
async (req, res) => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { reason, status, organizationType } = req.body
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { userId, organizationId } = req.params
Expand Down Expand Up @@ -334,7 +334,7 @@ export default (server: Server) => {
return res.status(200).send({})
}

if (organizationType === AccessEntityType.ENTREPRISE) {
if (mainRole.authorized_type === AccessEntityType.ENTREPRISE) {
/**
* if entreprise type of user is validated :
* - activate offer
Expand Down
7 changes: 7 additions & 0 deletions server/src/services/appLinks.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,13 @@ export function generateOffreToken(user: IUser2, offre: IJob) {
querystring: undefined,
},
}),
generateScope({
schema: zRoutes.post["/login/:userId/resend-confirmation-email"],
options: {
params: { userId: user._id.toString() },
querystring: undefined,
},
}),
],
{
expiresIn: "2h",
Expand Down
2 changes: 1 addition & 1 deletion server/src/services/etablissement.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ export const etablissementUnsubscribeDemandeDelegation = async (etablissementSir

export const autoValidateUserRoleOnCompany = async (userAndEntreprise: UserAndOrganization, origin: string) => {
const { isValid: validated, validator } = await isCompanyValid(userAndEntreprise)
const reason = `demande de validation à : ${validator}`
const reason = `validaton par : ${validator}`
if (validated) {
await authorizeUserOnEntreprise(userAndEntreprise, origin, reason)
} else {
Expand Down
3 changes: 2 additions & 1 deletion server/src/services/jobOpportunity.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { getSomeFtJobs } from "./ftjob.service"
import { TJobSearchQuery, TLbaItemResult } from "./jobOpportunity.service.types"
import { getSomeCompanies } from "./lbacompany.service"
import { ILbaItemLbaCompany, ILbaItemLbaJob, ILbaItemFtJob } from "./lbaitem.shared.service.types"
import { getLbaJobs } from "./lbajob.service"
import { getLbaJobs, incrementLbaJobsViewCount } from "./lbajob.service"
import { jobsQueryValidator } from "./queryValidator.service"

/**
Expand Down Expand Up @@ -159,6 +159,7 @@ export const getJobsQuery = async (

if ("matchas" in result && result.matchas && "results" in result.matchas) {
job_count += result.matchas.results.length
await incrementLbaJobsViewCount(result.matchas.results.flatMap((job) => (job?.id ? [job.id] : [])))
}

if (query.caller) {
Expand Down
2 changes: 1 addition & 1 deletion server/src/services/lbajob.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ export const getJobs = async ({ distance, lat, lon, romes, niveau }: { distance:
if (recruiter.is_delegated && recruiter.cfa_delegated_siret) {
const cfa = await Cfa.findOne({ siret: recruiter.cfa_delegated_siret })
const cfaUser = await getUser2ManagingOffer(recruiter.jobs[0])

recruiter.phone = cfaUser.phone
recruiter.email = cfaUser.email
recruiter.last_name = cfaUser.last_name
Expand Down Expand Up @@ -373,6 +372,7 @@ function transformLbaJobWithMinimalData({ recruiter, applicationCountByJob }: {
// si mandataire contient les données du CFA
siret: recruiter.establishment_siret,
name: recruiter.establishment_enseigne || recruiter.establishment_raison_sociale || "Enseigne inconnue",
mandataire: recruiter.is_delegated,
},
job: {
creationDate: offre.job_creation_date ? new Date(offre.job_creation_date) : null,
Expand Down
7 changes: 4 additions & 3 deletions server/src/services/userRecruteur.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,10 @@ export const userAndRoleAndOrganizationToUserRecruteur = (
}),
]
if (organisme && "status" in organisme) {
organisme.status
.flatMap((event) => (event.status === EntrepriseStatus.ERROR ? [entrepriseStatusEventToUserRecruteurStatusEvent(event, ETAT_UTILISATEUR.ERROR)] : []))
.forEach((event) => oldStatus.push(event))
const lastStatusEvent = getLastStatusEvent(organisme.status)
if (lastStatusEvent?.status === EntrepriseStatus.ERROR) {
oldStatus.push(entrepriseStatusEventToUserRecruteurStatusEvent(lastStatusEvent, ETAT_UTILISATEUR.ERROR))
}
}

const roleType = role.authorized_type === AccessEntityType.OPCO ? OPCO : role.authorized_type === AccessEntityType.ADMIN ? ADMIN : null
Expand Down
8 changes: 3 additions & 5 deletions shared/routes/login.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,9 @@ export const zLoginRoutes = {
"200": z.object({}).strict(),
},
securityScheme: {
auth: "cookie-session",
access: "user:manage",
resources: {
user: [{ _id: { key: "userId", type: "params" } }],
},
auth: "access-token",
access: null,
resources: {},
},
},
"/login/magiclink": {
Expand Down
2 changes: 1 addition & 1 deletion shared/routes/recruiters.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ export const zRecruiterRoutes = {
formulaire: ZRecruiter.optional(),
user: ZUser2,
token: z.string().optional(),
validated: z.boolean().optional(),
validated: z.boolean(),
})
.strict(),
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Box, Button, Flex, FormControl, FormErrorMessage, FormHelperText, FormL
import { Form, Formik } from "formik"
import { useRouter } from "next/router"
import { useContext, useState } from "react"
import { IRecruiterJson } from "shared"
import { IRecruiterJson, assertUnreachable } from "shared"
import { IUser2Json } from "shared/models/user2.model"
import * as Yup from "yup"

Expand Down Expand Up @@ -175,11 +175,13 @@ export const InformationCreationCompte = ({ isWidget = false }: { isWidget?: boo
pathname: isWidget ? "/espace-pro/widget/entreprise/offre" : "/espace-pro/creation/offre",
query: { establishment_id: data.formulaire.establishment_id, type, email: data.user.email, userId: data.user._id.toString(), token: data.token },
})
} else {
} else if (type === AUTHTYPE.CFA) {
router.push({
pathname: "/espace-pro/authentification/confirmation",
query: { email: data.user.email },
})
} else {
assertUnreachable(type)
}
} else {
validationPopup.onOpen()
Expand All @@ -192,10 +194,8 @@ export const InformationCreationCompte = ({ isWidget = false }: { isWidget?: boo
setSubmitting(false)
})
.catch((error) => {
console.error(error)
if (error instanceof ApiError) {
const payload: { error: string; statusCode: number; message: string } = error.context.errorData
setFieldError("email", payload.message)
setFieldError("email", error.message)
setSubmitting(false)
}
})
Expand Down
2 changes: 1 addition & 1 deletion ui/pages/espace-pro/creation/fin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ function FinComponent(props: ComponentProps) {
}

const resendMail = () => {
sendValidationLink(userId.toString())
sendValidationLink(userId.toString(), token)
.then(() => {
toast({
title: "Email envoyé.",
Expand Down
3 changes: 2 additions & 1 deletion ui/utils/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ export const updateEntrepriseAdmin = async (userId: string, user: any, siret = "
* Auth API
*/
export const sendMagiclink = async (email) => await API.post(`/login/magiclink`, email)
export const sendValidationLink = async (userId: string) => await apiPost("/login/:userId/resend-confirmation-email", { params: { userId } })
export const sendValidationLink = async (userId: string, token: string) =>
await apiPost("/login/:userId/resend-confirmation-email", { params: { userId }, headers: { authorization: `Bearer ${token}` } })

/**
* Etablissement API
Expand Down
Loading