fix: normaliser les URLs des connecteurs web
This commit is contained in:
@@ -2,6 +2,7 @@ import { z } from "zod";
|
||||
import { COOKIE_NAME } from "@shared/const";
|
||||
import { BAP_MIN_QUALITY_SCORE, meetsBapQualityThreshold } from "@shared/bapEligibility";
|
||||
import { calculateInvoiceQualityScore } from "@shared/invoiceQuality";
|
||||
import { webPortalUrlSchema } from "./webPortalUrl";
|
||||
|
||||
interface Condition {
|
||||
field: string;
|
||||
@@ -2577,7 +2578,7 @@ export const appRouter = router({
|
||||
saveSettings: protectedProcedure
|
||||
.input(
|
||||
z.object({
|
||||
portalUrl: z.string().url().optional(),
|
||||
portalUrl: webPortalUrlSchema.optional(),
|
||||
loginEmail: z.string().email().optional().or(z.literal('')),
|
||||
loginPassword: z.string().optional(), // vide = ne pas changer
|
||||
frequency: z.enum(['manual', 'daily', 'weekly', 'monthly']).optional(),
|
||||
@@ -2723,7 +2724,7 @@ export const appRouter = router({
|
||||
.input(z.object({
|
||||
name: z.string().min(1).max(100),
|
||||
connectorType: z.string().min(1).max(50),
|
||||
portalUrl: z.string().url(),
|
||||
portalUrl: webPortalUrlSchema,
|
||||
loginEmail: z.string().min(1),
|
||||
loginPassword: z.string().min(1),
|
||||
frequency: z.enum(['manual', 'daily', 'weekly', 'monthly']).default('monthly'),
|
||||
|
||||
49
server/webPortalUrl.test.ts
Normal file
49
server/webPortalUrl.test.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { isValidWebPortalUrl, normalizeWebPortalUrl } from "@shared/webPortalUrl";
|
||||
import { webPortalUrlSchema } from "./webPortalUrl";
|
||||
|
||||
describe("normalizeWebPortalUrl", () => {
|
||||
it("ajoute HTTPS aux adresses de portail saisies sans protocole", () => {
|
||||
expect(normalizeWebPortalUrl("www.sfr.fr/mon-espace-client")).toBe(
|
||||
"https://www.sfr.fr/mon-espace-client",
|
||||
);
|
||||
});
|
||||
|
||||
it("retire les espaces sans modifier une URL HTTPS déjà valide", () => {
|
||||
expect(normalizeWebPortalUrl(" https://pro.free.fr/ ")).toBe("https://pro.free.fr/");
|
||||
});
|
||||
|
||||
it("ne transforme pas un protocole non web en URL HTTPS", () => {
|
||||
expect(normalizeWebPortalUrl("ftp://example.org/factures")).toBe("ftp://example.org/factures");
|
||||
});
|
||||
});
|
||||
|
||||
describe("isValidWebPortalUrl", () => {
|
||||
it("accepte exclusivement les URLs HTTP ou HTTPS avec un hôte", () => {
|
||||
expect(isValidWebPortalUrl("https://espaceclient.orange.fr/")).toBe(true);
|
||||
expect(isValidWebPortalUrl("http://intranet.local/factures")).toBe(true);
|
||||
});
|
||||
|
||||
it("refuse les valeurs vides, incomplètes ou avec un protocole non web", () => {
|
||||
expect(isValidWebPortalUrl("")).toBe(false);
|
||||
expect(isValidWebPortalUrl("https://")).toBe(false);
|
||||
expect(isValidWebPortalUrl("ftp://example.org/factures")).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("webPortalUrlSchema", () => {
|
||||
it("normalise l’URL reçue par l’API avant de la persister", () => {
|
||||
expect(webPortalUrlSchema.parse("espaceclient.orange.fr")).toBe(
|
||||
"https://espaceclient.orange.fr",
|
||||
);
|
||||
});
|
||||
|
||||
it("retourne un message métier pour une URL de portail non HTTP(S)", () => {
|
||||
const result = webPortalUrlSchema.safeParse("ftp://example.org/factures");
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
if (!result.success) {
|
||||
expect(result.error.issues[0]?.message).toContain("URL HTTP(S) valide");
|
||||
}
|
||||
});
|
||||
});
|
||||
13
server/webPortalUrl.ts
Normal file
13
server/webPortalUrl.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { z } from "zod";
|
||||
import { isValidWebPortalUrl, normalizeWebPortalUrl } from "@shared/webPortalUrl";
|
||||
|
||||
/**
|
||||
* Normalise les domaines saisis sans protocole puis impose une URL HTTP(S).
|
||||
* Le même schéma est utilisé à la création et à la mise à jour d’un connecteur.
|
||||
*/
|
||||
export const webPortalUrlSchema = z
|
||||
.string()
|
||||
.transform(normalizeWebPortalUrl)
|
||||
.refine(isValidWebPortalUrl, {
|
||||
message: "Saisissez une URL HTTP(S) valide, par exemple https://espaceclient.exemple.fr.",
|
||||
});
|
||||
Reference in New Issue
Block a user