codevdesign 1.0.33 → 1.0.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/package.json +12 -6
  2. package/assets/csqc.css +0 -259
  3. package/composants/csqcAide.vue +0 -55
  4. package/composants/csqcAlerteErreur.vue +0 -87
  5. package/composants/csqcChaise/chaiseConteneur.vue +0 -367
  6. package/composants/csqcChaise/chaiseItem.vue +0 -54
  7. package/composants/csqcCodeBudgetaireGenerique.vue +0 -336
  8. package/composants/csqcConfirmation.vue +0 -75
  9. package/composants/csqcDate.vue +0 -57
  10. package/composants/csqcDialogue.vue +0 -118
  11. package/composants/csqcEditeurTexteRiche.vue +0 -380
  12. package/composants/csqcEntete.vue +0 -163
  13. package/composants/csqcImportCSV.vue +0 -125
  14. package/composants/csqcModaleSaisie.vue +0 -95
  15. package/composants/csqcOptionSwitch.vue +0 -120
  16. package/composants/csqcRecherche.vue +0 -213
  17. package/composants/csqcRechercheUtilisateur.vue +0 -197
  18. package/composants/csqcSnackbar.vue +0 -88
  19. package/composants/csqcTable/csqcTable.vue +0 -383
  20. package/composants/csqcTable/csqcTableExportExcel.vue +0 -58
  21. package/composants/csqcTable/csqcTableModaleChoixColonnes.vue +0 -586
  22. package/composants/csqcTexteBilingue.vue +0 -175
  23. package/composants/csqcTiroir.vue +0 -156
  24. package/composants/gabarit/csqcMenu.vue +0 -281
  25. package/composants/gabarit/pivEntete.vue +0 -205
  26. package/composants/gabarit/pivPiedPage.vue +0 -70
  27. package/composants/gabarit/vueDefault.vue +0 -5
  28. package/composants/validateurs.ts +0 -183
  29. package/enums/choixLangue.ts +0 -10
  30. package/index.ts +0 -74
  31. package/locales/en.json +0 -100
  32. package/locales/fr.json +0 -101
  33. package/modeles/apiReponse.ts +0 -12
  34. package/modeles/assurancesAssuranceGeneraleGrics.ts +0 -10
  35. package/modeles/assurancesAssurancePersonnelleGrics.ts +0 -13
  36. package/modeles/assurancesContratGrics.ts +0 -14
  37. package/modeles/assurancesDetailsPrimeReguliereGrics.ts +0 -12
  38. package/modeles/assurancesDonneesAssureurGrics.ts +0 -13
  39. package/modeles/assurancesEmployeGrics.ts +0 -11
  40. package/modeles/assurancesGrics.ts +0 -14
  41. package/modeles/assurancesRegimeAssuranceGrics.ts +0 -9
  42. package/modeles/assurancesRegimeBaseEmployeurGrics.ts +0 -9
  43. package/modeles/assurancesRegimeBaseGrics.ts +0 -9
  44. package/modeles/composants/csqcMenuModele.ts +0 -18
  45. package/modeles/composants/datatableColonne.ts +0 -31
  46. package/modeles/composants/snackbar.ts +0 -18
  47. package/modeles/data.ts +0 -24
  48. package/modeles/droitIntervention.ts +0 -14
  49. package/modeles/employeAdresseGrics.ts +0 -13
  50. package/modeles/employeAdressesPersonnellesGrics.ts +0 -12
  51. package/modeles/employeAffectationCorpsEmploiGrics.ts +0 -9
  52. package/modeles/employeBanquesCongeBanqueGrics.ts +0 -9
  53. package/modeles/employeBanquesCongeGrics.ts +0 -14
  54. package/modeles/employeBanquesCongeRegimeAbsenceGrics.ts +0 -9
  55. package/modeles/employeCourrielsPersonnels.ts +0 -9
  56. package/modeles/employeCourrielsProfessionnels.ts +0 -9
  57. package/modeles/employeEmploisCategorieGrics.ts +0 -9
  58. package/modeles/employeEmploisClasseGrics.ts +0 -9
  59. package/modeles/employeEmploisCorpsEmploiGrics.ts +0 -9
  60. package/modeles/employeEmploisEtatEmploiGrics.ts +0 -9
  61. package/modeles/employeEmploisGrics.ts +0 -37
  62. package/modeles/employeEmploisGroupePaieGrics.ts +0 -9
  63. package/modeles/employeEmploisLieuTravailPrincipalGrics.ts +0 -10
  64. package/modeles/employeEmploisLieuxTravailSecondairesGrics.ts +0 -10
  65. package/modeles/employeEmploisRegimeAbsenceGrics.ts +0 -9
  66. package/modeles/employeEmploisSecteurGrics.ts +0 -9
  67. package/modeles/employeEmploisStatutEngagementGrics.ts +0 -9
  68. package/modeles/employeExperienceEmploiGrics.ts +0 -9
  69. package/modeles/employeExperienceEmployeGrics.ts +0 -12
  70. package/modeles/employeExperienceExperiencesGrics.ts +0 -11
  71. package/modeles/employeExperienceExperiencesTotalesGrics.ts +0 -15
  72. package/modeles/employeExperienceGrics.ts +0 -17
  73. package/modeles/employeGrics.ts +0 -31
  74. package/modeles/employeMinsLsCodev.ts +0 -10
  75. package/modeles/employeTelephoneGrics.ts +0 -12
  76. package/modeles/employeTelephonesPersonnelsGrics.ts +0 -11
  77. package/modeles/employeTelephonesProfessionnelsGrics.ts +0 -11
  78. package/modeles/groupeCE.ts +0 -14
  79. package/modeles/groupeCEIntervalle.ts +0 -13
  80. package/modeles/historiquesAbsenceBanqueGrics.ts +0 -9
  81. package/modeles/historiquesAbsenceGrics.ts +0 -21
  82. package/modeles/historiquesAbsenceLieuTravailGrics.ts +0 -9
  83. package/modeles/historiquesAbsenceSousBanqueGrics.ts +0 -9
  84. package/modeles/intervention.ts +0 -35
  85. package/modeles/motifsAbsenceBanque.ts +0 -9
  86. package/modeles/motifsAbsenceGrics.ts +0 -17
  87. package/modeles/motifsAbsenceRegimeAbsence.ts +0 -9
  88. package/modeles/motifsAbsenceSousMotifs.ts +0 -9
  89. package/modeles/motifsAbsenceTraitementBanques.ts +0 -11
  90. package/modeles/notificationGabaritDefaut.ts +0 -10
  91. package/modeles/response.ts +0 -12
  92. package/modeles/role.ts +0 -31
  93. package/modeles/roleMin.ts +0 -12
  94. package/modeles/syndicat.ts +0 -26
  95. package/modeles/syndicatGroupeCe.ts +0 -10
  96. package/modeles/syndicatResponsable.ts +0 -15
  97. package/modeles/syndicatUnite.ts +0 -10
  98. package/modeles/typeEnseignement.ts +0 -14
  99. package/modeles/typeTelephone.ts +0 -12
  100. package/modeles/unite.ts +0 -23
  101. package/modeles/uniteTypeEnseignement.ts +0 -12
  102. package/modeles/utilisateur.ts +0 -15
  103. package/outils/appAxios.ts +0 -116
  104. package/outils/csqcOutils.ts +0 -366
  105. package/outils/rafraichisseurToken.ts +0 -187
@@ -1,366 +0,0 @@
1
- /** ATTENTION
2
- * Ne pas ajouter ou modifier de fonctions ici. Créer son propre fichier d'outils pour votre app.
3
- * Ces outils sont des outils communs.
4
- * */
5
-
6
- class CSQCOutils {
7
- racineLocalStorage = 'csqc_CodevDesign'
8
-
9
- /**
10
- * Concatène une string avec le marqueur de séparation demandée.
11
- * @param texteOrigine Le texte d'origine
12
- * @param texteAjoute Le texte a concaténer
13
- * @param separateur (Default: ', ') Le séparateur à ajouter entre les deux textes.
14
- * */
15
- ConcateneTexte(texteOrigine: string, texteAjoute: string, separateur: string = ', ') {
16
- let retour = texteOrigine
17
- if (this.TexteVide(texteOrigine) === false) {
18
- retour += separateur
19
- }
20
-
21
- return retour + texteAjoute
22
- }
23
-
24
- /**
25
- * Retourne true si le texte n'est pas défini ou s'il est null ou vide. Tous les espaces sont retirés par défaut.
26
- * @param texte Le texte a inspecter.
27
- * @param retirerEspace (Default: true) Si true, les espaces seront enlevés du texte
28
- */
29
- TexteVide(texte?: string | null, retirerEspace = true) {
30
- let retour = texte === undefined || texte == null || texte === ''
31
- if (retour === false && retirerEspace === true) {
32
- const temp = texte
33
- retour = temp?.replace(' ', '') === ''
34
- }
35
-
36
- return retour
37
- }
38
-
39
- /**
40
- * Pad un texte avec des caractères à gauche
41
- * @param texte Texte à padder
42
- * @param caractere Caractère à utiliser
43
- * @param longueurFinale Longueur finale à atteindre
44
- */
45
- PadGauche(texte: string, caractere: string, longueurFinale: number) {
46
- while (texte.length < longueurFinale) {
47
- texte = caractere + texte
48
- }
49
- return texte
50
- }
51
-
52
- /**
53
- * Pad un texte avec des caractères à droite
54
- * @param texte Texte à padder
55
- * @param caractere Caractère à utiliser
56
- * @param longueurFinale Longueur finale à atteindre
57
- */
58
- PadDroit(texte: string, caractere: string, longueurFinale: number) {
59
- while (texte.length < longueurFinale) {
60
- texte += caractere
61
- }
62
- return texte
63
- }
64
-
65
- /**
66
- * Transforme un nombre en string en arrondissant au nombre maximal de décimales.
67
- * Ex : 14,57582 avec un affichage sur 2 décimales sera 15,58
68
- * Si le nombre est 14,6 avec 2 décimales, le retour sera 14,6
69
- * @param nombre Nombre à transformer en string
70
- * @param nbDecimale Nombre maximal de décimales à afficher
71
- */
72
- DecimaleVariable(nombre: number, nbDecimale: number) {
73
- let valeurRetour = 0
74
- while (valeurRetour === 0 && nbDecimale > 0) {
75
- const multiplicateur = 10 ** (nbDecimale - 1)
76
- valeurRetour = (nombre * multiplicateur) % 1
77
- if (valeurRetour === 0) {
78
- nbDecimale -= 1
79
- }
80
- }
81
- let retour = nombre.toFixed(nbDecimale)
82
- // Retirer les derniers 0 ayant pu s'inscruster dû aux arrondissements.
83
- while (retour.length > 1 && retour.lastIndexOf('0') === retour.length - 1) {
84
- retour = retour.substring(0, retour.length - 1)
85
- }
86
- if (retour.lastIndexOf('.') === retour.length - 1) {
87
- retour = retour.substring(0, retour.length - 1) // Retirer le point s'il termine le nombre
88
- }
89
- return retour.replace('.', ',')
90
- }
91
-
92
- /**
93
- * Transforme un nombre en string en y mettant le nombre de décimale à afficher.
94
- * @param nombre Nombre à transformer en string
95
- * @param nbDecimale Nombre de décimales à afficher
96
- */
97
- DecimaleNonVariable(nombre: number, nbDecimale: number) {
98
- return this.DecimaleVersString(nombre, nbDecimale, false).replace('.', ',')
99
- }
100
-
101
- /**
102
- * Transforme un boolean en string avec la première lettre minuscule.
103
- * @param bool Bool à mettre en string
104
- */
105
- BoolVersString(bool: boolean) {
106
- if (bool === true) {
107
- return 'true'
108
- }
109
- return 'false'
110
- }
111
-
112
- /**
113
- * Transforme une string en nombre.
114
- * @param texte string à mettre en number. Peut-être un entier ou une décimale avec virgule ou point
115
- */
116
- StringVersNombre(texte: string) {
117
- texte = texte.replace(',', '.') // On remplace les virgules par des points.
118
- return Number(texte)
119
- }
120
-
121
- /**
122
- * Transforme une string en number avec des options pour le nombre de décimales.
123
- * @param nombre Nombre à transformer
124
- * @param nbDecimale Nombre de décimales à afficher au maximum
125
- * @param afficherDecimaleVariable Si true, alors on affiche que les décimales nécessaires,
126
- * jusqu'à nbDecimale. Ex : 4,2 et 4,25 Si False, nous auront 4,20 et 4,25
127
- * @param separateur Séparateur à utiliser pour la décimale.
128
- * La virgule ou le point. La virgule est utilisée par défaut.
129
- */
130
- DecimaleVersString(nombre: number, nbDecimale: number, afficherDecimaleVariable: boolean, separateur: string = ',') {
131
- let retour = ''
132
- if (afficherDecimaleVariable === true) {
133
- retour = this.DecimaleVariable(nombre, nbDecimale)
134
- } else {
135
- retour = nombre.toFixed(nbDecimale)
136
- }
137
- retour.replace('.', separateur)
138
- return retour
139
- }
140
-
141
- /**
142
- * Transforme une décimale en formateur heure:minute. Ex : 2,5 => 2:30
143
- * @param heures Nombre à mettre en string de type heure.
144
- * @param separateur Séparateur heure, minute. Le : est utilisé par défaut.
145
- */
146
- DecimaleVersHeure(heures: number, separateur: string = ':') {
147
- if (Math.round((heures % 1) * 60) < 10) {
148
- return `${Math.floor(heures) + separateur}0${Math.round((heures % 1) * 60)}`
149
- }
150
- return Math.floor(heures) + separateur + Math.round((heures % 1) * 60)
151
- }
152
-
153
- /**
154
- * Transforme différent type de fin de ligne comme des \n en <br />
155
- * @param texte Texte à modifier et retourner
156
- */
157
- FinLigneVersBR(texte: string) {
158
- return texte.replace(/(?:\r\n|\r|\n)/g, '<br />')
159
- }
160
-
161
- /**
162
- * Transforme une date en string.
163
- * Le principe est de séparer la string selon le séparateur et de créer une nouvelle date avec les 3 nombres que ça donne.
164
- * @param dateStr Date en string
165
- */
166
- StringVersDate(dateStr: string, separateur = '-') {
167
- const parties = dateStr.split(separateur)
168
- if (parties.length < 3) {
169
- throw new Error(`Conversion de date invalide. Format incorrect, attendu (yyyy-mm-dd), reçu : ${dateStr}`)
170
- }
171
- const retourDateTemp = new Date(
172
- this.StringVersNombre(parties[0]),
173
- this.StringVersNombre(parties[1]) - 1,
174
- this.StringVersNombre(parties[2]),
175
- 0,
176
- 0,
177
- 0,
178
- 0,
179
- ) // Les mois débutent le compte à 0.
180
- return retourDateTemp
181
- }
182
-
183
- /**
184
- * Transforme une date en string sous la forme YYYY-mm-dd
185
- * @param date Date à mettre en string
186
- */
187
- DateVersString(date: Date) {
188
- let month = `${date.getMonth() + 1}`
189
- let day = `${date.getDate()}`
190
- const year = date.getFullYear()
191
- if (month.length < 2) {
192
- month = `0${month}`
193
- }
194
- if (day.length < 2) {
195
- day = `0${day}`
196
- }
197
- return [year, month, day].join('-')
198
- }
199
-
200
- /**
201
- * Retourne la valeur numérique d'un nombre sous forme de string. Si le texte n'est pas un nombre NAN sera retourné.
202
- * @param texte Texte à transformer en nombre
203
- */
204
- ValeurNumeriqueDepuisTexte(texte: string) {
205
- return parseFloat(texte)
206
- }
207
-
208
- /**
209
- * Fabriquer une nouvelle instance de l'objet à retournet et y assigne tous les attributs publiques de la source.
210
- * Si un attribut n'existe pas dans la définition de la classe du type de retour, il sera quand même créé dynamiquement et aucune erreur ne sera soulevée
211
- * Si le constructeur
212
- * @param donneeBrut Objet de donnée brut source
213
- */
214
- FabriquerUnObjetAnonyme(source: object) {
215
- return JSON.parse(JSON.stringify(source))
216
- }
217
-
218
- Cloner(objetAnonyme: object) {
219
- return this.FabriquerUnObjetAnonyme(objetAnonyme)
220
- }
221
-
222
- /**
223
- * Fabriquer une nouvelle instance de l'objet à retourner et lui assigne tous les attributs publiques de la source.
224
- * Si un attribut n'existe pas dans la définition de la classe du type de retour, il sera quand même créé dynamiquement et aucune erreur ne sera soulevée
225
- * @param source L'objet source
226
- * @param destination L'objet destinataire
227
- */
228
- CopierObjetUnNiveau(source: any, destination: any) {
229
- Object.keys(source).forEach(k => {
230
- if (!Array.isArray(source[k])) {
231
- destination[k] = source[k]
232
- }
233
- })
234
-
235
- return destination
236
- }
237
-
238
- /**
239
- * Bind les attributs d'un objet vers un autre. Les attributs de la source qui n'existe pas dans la destination seront créés automatiquement
240
- * @param source Objet de donnée brut source
241
- * @param destination Objet de donnée brut source
242
- */
243
- BinderDonnee(source: any, destination: any) {
244
- if (destination == null) {
245
- destination = {}
246
- }
247
-
248
- Object.keys(source).forEach(k => {
249
- destination[k] = source[k]
250
- })
251
- return destination
252
- }
253
-
254
-
255
- SetThemeDark(valeur: any) {
256
- localStorage.setItem(`${this.racineLocalStorage}ThemeDark`, valeur)
257
- }
258
-
259
- GetThemeDark() {
260
- const valeur = localStorage.getItem(`${this.racineLocalStorage}ThemeDark`)
261
-
262
- if (typeof valeur === 'string') {
263
- if (valeur === 'true') {
264
- return true
265
- }
266
-
267
- return false
268
- }
269
-
270
- return valeur
271
- }
272
-
273
- GetUrlBaseAPI() {
274
- let baseUrl = window.location.origin
275
- if (this.TexteVide(window.Location.prototype.pathname) === false) {
276
- baseUrl += window.Location.prototype.pathname
277
- }
278
- baseUrl += '/api/'
279
-
280
- return baseUrl
281
- }
282
-
283
- estDateAvantOuEgaleAujourdhui(date: string, comparerHeure: boolean) {
284
- const now = new Date()
285
- const dateDebut = new Date(this.StringVersDate(date))
286
-
287
- if (comparerHeure === false) {
288
- now.setHours(0, 0, 0, 0)
289
- dateDebut.setHours(0, 0, 0, 0)
290
- }
291
-
292
- if (dateDebut <= now) {
293
- return false
294
- }
295
-
296
- return true
297
- }
298
-
299
- estDateAvantAujourdhui(date: string, comparerHeure: boolean) {
300
- const now = new Date()
301
- const dateDebut = new Date(this.StringVersDate(date))
302
-
303
- if (comparerHeure === false) {
304
- now.setHours(0, 0, 0, 0)
305
- dateDebut.setHours(0, 0, 0, 0)
306
- }
307
-
308
- if (dateDebut < now) {
309
- return false
310
- }
311
-
312
- return true
313
- }
314
-
315
- estDateApresOuEgaleAujourdhui(date: string, comparerHeure: boolean) {
316
- const now = new Date()
317
- const dateDebut = new Date(this.StringVersDate(date))
318
-
319
- if (comparerHeure === false) {
320
- now.setHours(0, 0, 0, 0)
321
- dateDebut.setHours(0, 0, 0, 0)
322
- }
323
-
324
- if (dateDebut >= now) {
325
- return false
326
- }
327
-
328
- return true
329
- }
330
-
331
- estDateApresAujourdhui(date: string, comparerHeure: boolean) {
332
- const now = new Date()
333
- const dateDebut = new Date(this.StringVersDate(date))
334
-
335
- if (comparerHeure === false) {
336
- now.setHours(0, 0, 0, 0)
337
- dateDebut.setHours(0, 0, 0, 0)
338
- }
339
-
340
- if (dateDebut > now) {
341
- return false
342
- }
343
-
344
- return true
345
- }
346
-
347
- /**
348
- * Converti un enum en objet clé-valeur pour usage dans la prop :items d'un v-select.
349
- * @param _obj L'enum pour générer les clés-valeurs
350
- * @returns Une liste d'objets du format { title: string, value: number }
351
- */
352
- genererItemsAPartirDeEnum<T extends object>(_enum: T) {
353
- const enumKeys = Object.keys(_enum).filter(e => isNaN(Number(e)))
354
- const enumValues = Object.keys(_enum).filter(e => !isNaN(Number(e))).map(e => Number(e))
355
-
356
- const ret: { title?: string, value: number}[] = []
357
-
358
- enumValues.forEach(v => ret.push({ title: enumKeys[v], value: v}))
359
-
360
- return ret;
361
- }
362
- }
363
-
364
- const csqcOutils = new CSQCOutils()
365
-
366
- export default csqcOutils
@@ -1,187 +0,0 @@
1
- class RafraichisseurToken {
2
- private intervalleEnSecondes = 15
3
- private secondesAvantExpirationTokenPourRafraichir = 20
4
- private skewSeconds = 5 // marge anti-derives d’horloge
5
- private popupAffiche = false
6
- private timerId: number | null = null
7
-
8
- // Lance une seule fois
9
- public async demarrer(nomTemoin: string | null, urlPortail: string): Promise<void> {
10
- urlPortail = urlPortail.replace(/\/+$/, '')
11
- if (nomTemoin == null || nomTemoin === '') nomTemoin = 'csqc_jeton_secure_expiration'
12
- await this.verifierJeton(nomTemoin, urlPortail)
13
- if (this.timerId != null) return
14
- this.timerId = window.setInterval(() => {
15
- this.verifierJeton(nomTemoin, urlPortail)
16
- }, this.intervalleEnSecondes * 1000)
17
- }
18
-
19
- // Permet d’arrêter le timer (ex: au logout / destroy)
20
- public arreter(): void {
21
- if (this.timerId != null) {
22
- clearInterval(this.timerId)
23
- this.timerId = null
24
- }
25
- }
26
-
27
- public existeJeton = (nomTemoin: string) => {
28
- return this.estJetonValide(nomTemoin)
29
- }
30
-
31
- private async verifierJeton(nomTemoin: string, urlPortail: string): Promise<void> {
32
- if (this.popupAffiche) return
33
-
34
- if (!this.estJetonValide(nomTemoin)) {
35
- this.rafraichir(nomTemoin, urlPortail)
36
- return
37
- }
38
- }
39
-
40
- private estJetonValide(nomTemoin: string): boolean {
41
- if (this.popupAffiche || !nomTemoin) return true //On fait semblant que c'est valide pour ne pas provoquer un autre affichage du popup.
42
-
43
- const tokenEncode = this.lireCookie(nomTemoin)
44
- if (!tokenEncode) {
45
- return false
46
- }
47
-
48
- let token: any
49
- try {
50
- token = this.parseJwt(tokenEncode)
51
- } catch {
52
- return false
53
- }
54
-
55
- const exp = Number(token?.exp)
56
- if (!Number.isFinite(exp)) {
57
- // exp manquant/invalide → tente refresh
58
-
59
- return false
60
- }
61
-
62
- const now = Math.floor(Date.now() / 1000)
63
- const refreshAt = exp - this.secondesAvantExpirationTokenPourRafraichir - this.skewSeconds
64
- if (now >= refreshAt) {
65
- return false
66
- }
67
-
68
- return true
69
- }
70
-
71
- private async rafraichir(nomCookie: string, urlPortail: string): Promise<void> {
72
- if (!nomCookie) return
73
- const url = this.getRefreshUrl(urlPortail)
74
- const controller = new AbortController()
75
- const timeout = setTimeout(() => controller.abort(), 10_000)
76
-
77
- try {
78
- //Première tentative sans iframe, pour la majorité des cas.
79
- const resp = await fetch(url, {
80
- method: 'POST',
81
- credentials: 'include',
82
- headers: { Accept: 'application/json' },
83
- redirect: 'manual',
84
- signal: controller.signal,
85
- })
86
-
87
- // redirection (souvent => login) → traiter comme non auth
88
-
89
- if (resp.type === 'opaqueredirect' || resp.status === 302) {
90
- this.rafraichirParIframe(nomCookie, urlPortail)
91
- return
92
- }
93
-
94
- // OK ou No Content: le cookie devrait être réécrit
95
- if (resp.status === 200 || resp.status === 204) {
96
- const jeton = this.lireCookie(nomCookie)
97
- if (!jeton) this.rafraichirParIframe(nomCookie, urlPortail)
98
- return
99
- }
100
-
101
- // non auth / expiré (401, 419) + IIS timeout (440)
102
- if (resp.status === 401 || resp.status === 419 || resp.status === 440) {
103
- this.rafraichirParIframe(nomCookie, urlPortail)
104
- return
105
- }
106
-
107
- console.warn('Rafraichisseur token: statut inattendu', resp.status)
108
- } catch (err: any) {
109
- if (err?.name === 'AbortError') console.warn('RafraichisseurToken timeout')
110
- else console.error('Erreur rafraichisseur de token', err)
111
- // on réessaiera au prochain tick
112
- } finally {
113
- clearTimeout(timeout)
114
- }
115
- }
116
-
117
- private rafraichirParIframe(nomCookie: string, urlPortail: string): void {
118
- // Pour éviter les cross référence, on créé un iframe qui appel portail et force la MAJ du jeton ou l'invalidation du jeton, si jamais l'utilisateur n'est plus connecté
119
- // ajax vers le refresh
120
- let iframe = document.createElement('iframe')
121
- const url = this.getRefreshUrl(urlPortail)
122
- iframe.src = `${url}?urlRetour=${encodeURI(window.localStorage.href)}`
123
- iframe.id = 'idRafrToken'
124
- iframe.style.display = 'none'
125
- document.body.appendChild(iframe)
126
- iframe.onload = () => {
127
- const jetonCSQC = this.lireCookie(nomCookie)
128
- if (jetonCSQC == null || jetonCSQC === '') {
129
- this.estDeconnecteAzure(urlPortail)
130
- }
131
-
132
- iframe.remove()
133
- }
134
- }
135
-
136
- private estDeconnecteAzure(urlPortail: string): void {
137
- //on envoie au portail, pas le choix
138
-
139
- const retour = encodeURI(window.location.href)
140
- window.open(`${urlPortail}/home/SeConnecter?urlRetour=${retour}`, '_self')
141
- return
142
- }
143
-
144
- public deconnecterPortail(urlPortail: string): void {
145
- window.location.replace(`${urlPortail}/deconnecte?urlRetour=${encodeURIComponent(window.location.href)}`)
146
- }
147
-
148
- private lireCookie(nom: string): string | null {
149
- if (!document.cookie) return null
150
- const cookies = document.cookie.split(';').map(c => c.trim())
151
- for (const cookie of cookies) {
152
- if (cookie.startsWith(`${nom}=`)) {
153
- try {
154
- return decodeURIComponent(cookie.substring(nom.length + 1))
155
- } catch {
156
- return cookie.substring(nom.length + 1)
157
- }
158
- }
159
- }
160
- return null
161
- }
162
-
163
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
164
- private parseJwt(token: string): any {
165
- const parts = token.split('.')
166
- const base64Url = parts[1]
167
- if (!base64Url) throw new Error('Invalid JWT format')
168
- const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/')
169
- const jsonPayload = decodeURIComponent(
170
- atob(base64)
171
- .split('')
172
- .map(c => `%${`00${c.charCodeAt(0).toString(16)}`.slice(-2)}`)
173
- .join(''),
174
- )
175
- return JSON.parse(jsonPayload)
176
- }
177
-
178
- // URL refresh selon env (dev = proxy Vite ; prod = portail)
179
- private getRefreshUrl(urlPortail: string): string {
180
- if (import.meta.env.MODE === 'development') return '/portail-refresh'
181
- return urlPortail + '/home/Refresh'
182
- }
183
- }
184
-
185
- // Instance
186
- const rafraichisseurToken = new RafraichisseurToken()
187
- export default rafraichisseurToken