codevdesign 1.0.74 → 1.0.75
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.
- package/composants/csqcAide.vue +55 -55
- package/composants/csqcAlerteErreur.vue +87 -87
- package/composants/csqcChaise/chaiseConteneur.vue +372 -372
- package/composants/csqcChaise/chaiseItem.vue +54 -54
- package/composants/csqcConfirmation.vue +75 -75
- package/composants/csqcEditeurTexteRiche.vue +378 -378
- package/composants/csqcEntete.vue +229 -229
- package/composants/csqcImportCSV.vue +125 -125
- package/composants/csqcSnackbar.vue +207 -207
- package/composants/csqcSwitch.vue +220 -220
- package/composants/csqcTable/csqcTableExportExcel.vue +46 -46
- package/composants/csqcTexteBilingue.vue +175 -175
- package/composants/csqcTiroir.vue +195 -195
- package/composants/gabarit/csqcMenu.vue +281 -281
- package/editeur.ts +1 -1
- package/importCSV.ts +1 -1
- package/index.ts +80 -80
- package/modeles/composants/csqcMenuModele.ts +18 -18
- package/modeles/composants/datatableColonne.ts +31 -31
- package/outils/appAxios.ts +113 -113
- package/outils/rafraichisseurToken.ts +81 -52
- package/package.json +1 -1
|
@@ -7,24 +7,38 @@ class RafraichisseurToken {
|
|
|
7
7
|
private nomTemoin = 'csqc_jeton_secure_expiration'
|
|
8
8
|
private urlPortail = ''
|
|
9
9
|
private refreshPromise: Promise<void> | null = null
|
|
10
|
+
public loggerTrace = false
|
|
10
11
|
|
|
11
12
|
// Lance une seule fois
|
|
12
|
-
public async demarrer(nomTemoin: string
|
|
13
|
-
|
|
14
|
-
if (
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
public async demarrer(nomTemoin: string, urlPortail: string): Promise<void> {
|
|
14
|
+
window.rafraichisseurToken = this
|
|
15
|
+
if (this.loggerTrace) {
|
|
16
|
+
console.log('Nom témoin', nomTemoin)
|
|
17
|
+
console.log('URL portail', urlPortail)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (nomTemoin == null || nomTemoin === '') {
|
|
21
|
+
console.warn('[RafraichisseurToken] nomTemoin invalide, rafraichisseur de token désactivé')
|
|
22
|
+
return
|
|
23
|
+
}
|
|
24
|
+
if (urlPortail == null || urlPortail === '') {
|
|
25
|
+
console.warn('[RafraichisseurToken] urlPortail invalide, rafraichisseur de token désactivé')
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
this.nomTemoin = nomTemoin
|
|
29
|
+
this.urlPortail = urlPortail.replace(/\/+$/, '')
|
|
30
|
+
|
|
31
|
+
await this.verifierJeton()
|
|
18
32
|
if (this.timerId != null) return
|
|
19
33
|
this.timerId = window.setInterval(() => {
|
|
20
|
-
this.verifierJeton(
|
|
34
|
+
this.verifierJeton()
|
|
21
35
|
}, this.intervalleEnSecondes * 1000)
|
|
22
36
|
}
|
|
23
37
|
|
|
24
38
|
public attendreRefreshSiNecessaire(force = false): Promise<void> {
|
|
25
39
|
if (this.refreshPromise) return this.refreshPromise
|
|
26
|
-
if (force || !this.estJetonValide(
|
|
27
|
-
this.refreshPromise = this.rafraichir(
|
|
40
|
+
if (force || !this.estJetonValide()) {
|
|
41
|
+
this.refreshPromise = this.rafraichir().finally(() => {
|
|
28
42
|
this.refreshPromise = null
|
|
29
43
|
})
|
|
30
44
|
return this.refreshPromise
|
|
@@ -40,28 +54,30 @@ class RafraichisseurToken {
|
|
|
40
54
|
}
|
|
41
55
|
}
|
|
42
56
|
|
|
43
|
-
public existeJeton = (
|
|
44
|
-
return this.estJetonValide(
|
|
57
|
+
public existeJeton = () => {
|
|
58
|
+
return this.estJetonValide()
|
|
45
59
|
}
|
|
46
60
|
|
|
47
|
-
private async verifierJeton(
|
|
48
|
-
if (this.
|
|
61
|
+
private async verifierJeton(): Promise<void> {
|
|
62
|
+
if (this.loggerTrace) console.log('[RafraichisseurToken] Vérification du jeton...')
|
|
63
|
+
if (this.popupAffiche) {
|
|
64
|
+
if (this.loggerTrace) console.log('[RafraichisseurToken] Popup affiché, vérification du jeton ignorée')
|
|
65
|
+
return
|
|
66
|
+
}
|
|
49
67
|
|
|
50
|
-
if (!this.estJetonValide(
|
|
68
|
+
if (!this.estJetonValide()) {
|
|
51
69
|
if (!this.refreshPromise) {
|
|
52
|
-
this.refreshPromise = this.rafraichir(
|
|
70
|
+
this.refreshPromise = this.rafraichir().finally(() => {
|
|
53
71
|
this.refreshPromise = null
|
|
54
72
|
})
|
|
55
73
|
}
|
|
56
74
|
}
|
|
57
75
|
}
|
|
58
76
|
|
|
59
|
-
private estJetonValide(
|
|
60
|
-
if (this.popupAffiche
|
|
61
|
-
|
|
77
|
+
private estJetonValide(): boolean {
|
|
78
|
+
if (this.popupAffiche) return true //On fait semblant que c'est valide pour ne pas provoquer un autre affichage du popup.
|
|
62
79
|
|
|
63
|
-
|
|
64
|
-
const tokenEncode = this.lireCookie(nomTemoin)
|
|
80
|
+
const tokenEncode = this.lireCookie()
|
|
65
81
|
if (!tokenEncode) {
|
|
66
82
|
return false
|
|
67
83
|
}
|
|
@@ -87,12 +103,12 @@ class RafraichisseurToken {
|
|
|
87
103
|
return true
|
|
88
104
|
}
|
|
89
105
|
|
|
90
|
-
private async rafraichir(
|
|
91
|
-
if (
|
|
92
|
-
|
|
93
|
-
if (urlPortail == null || urlPortail == '') return
|
|
106
|
+
private async rafraichir(): Promise<void> {
|
|
107
|
+
if (this.loggerTrace) console.log('[RafraichisseurToken] rafraichir() appelé')
|
|
108
|
+
|
|
109
|
+
if (this.urlPortail == null || this.urlPortail == '') return
|
|
94
110
|
this.popupAffiche = true // bloquer tout nouveau tick pendant le refresh
|
|
95
|
-
const url = this.getRefreshUrl(
|
|
111
|
+
const url = this.getRefreshUrl()
|
|
96
112
|
const controller = new AbortController()
|
|
97
113
|
const timeout = setTimeout(() => controller.abort(), 10_000)
|
|
98
114
|
|
|
@@ -107,18 +123,18 @@ class RafraichisseurToken {
|
|
|
107
123
|
})
|
|
108
124
|
|
|
109
125
|
// redirection vers Azure AD → session expirée, l'iframe ne peut pas compléter le flow OIDC cross-site
|
|
110
|
-
|
|
126
|
+
if (this.loggerTrace) console.log('[RafraichisseurToken] fetch réponse type:', resp.type, 'status:', resp.status)
|
|
111
127
|
if (resp.type === 'opaqueredirect' || resp.status === 302) {
|
|
112
|
-
this.estDeconnecteAzure(
|
|
128
|
+
this.estDeconnecteAzure()
|
|
113
129
|
return
|
|
114
130
|
}
|
|
115
131
|
|
|
116
132
|
// OK ou No Content: le cookie devrait être réécrit
|
|
117
133
|
if (resp.status === 200 || resp.status === 204) {
|
|
118
|
-
const jeton = this.lireCookie(
|
|
134
|
+
const jeton = this.lireCookie()
|
|
119
135
|
if (!jeton) {
|
|
120
|
-
|
|
121
|
-
this.rafraichirParIframe(
|
|
136
|
+
if (this.loggerTrace) console.log('[RafraichisseurToken] 200 mais cookie absent → iframe')
|
|
137
|
+
this.rafraichirParIframe()
|
|
122
138
|
} else {
|
|
123
139
|
this.popupAffiche = false // succès, reprendre la surveillance
|
|
124
140
|
}
|
|
@@ -127,8 +143,8 @@ class RafraichisseurToken {
|
|
|
127
143
|
|
|
128
144
|
// non auth / expiré (401, 419) + IIS timeout (440)
|
|
129
145
|
if (resp.status === 401 || resp.status === 419 || resp.status === 440) {
|
|
130
|
-
|
|
131
|
-
this.rafraichirParIframe(
|
|
146
|
+
if (this.loggerTrace) console.log('[RafraichisseurToken] statut auth → iframe')
|
|
147
|
+
this.rafraichirParIframe()
|
|
132
148
|
return
|
|
133
149
|
}
|
|
134
150
|
|
|
@@ -143,10 +159,10 @@ class RafraichisseurToken {
|
|
|
143
159
|
}
|
|
144
160
|
}
|
|
145
161
|
|
|
146
|
-
private rafraichirParIframe(
|
|
162
|
+
private rafraichirParIframe(): void {
|
|
147
163
|
this.popupAffiche = true // bloquer le timer pendant que l'iframe tente l'auth
|
|
148
164
|
let iframe = document.createElement('iframe')
|
|
149
|
-
const url = this.getRefreshUrl(
|
|
165
|
+
const url = this.getRefreshUrl()
|
|
150
166
|
iframe.src = `${url}?urlRetour=${encodeURI(window.location.href)}`
|
|
151
167
|
iframe.id = 'idRafrToken'
|
|
152
168
|
iframe.style.display = 'none'
|
|
@@ -161,13 +177,15 @@ class RafraichisseurToken {
|
|
|
161
177
|
}, 15_000)
|
|
162
178
|
|
|
163
179
|
iframe.onload = () => {
|
|
180
|
+
if (this.loggerTrace) console.log('[RafraichisseurToken] iframe onload, vérification du jeton...')
|
|
164
181
|
clearTimeout(iframeTimeout)
|
|
165
182
|
iframe.onload = null // empêcher les re-entrées sur les redirects OIDC internes
|
|
166
|
-
|
|
167
|
-
const
|
|
168
|
-
const jeton = this.lireCookie(cookieAVerifier)
|
|
183
|
+
|
|
184
|
+
const jeton = this.lireCookie()
|
|
169
185
|
if (jeton == null || jeton === '') {
|
|
170
|
-
this.
|
|
186
|
+
if (this.loggerTrace)
|
|
187
|
+
console.log('[RafraichisseurToken] iframe onload, jeton toujours absent → déconnecté Azure')
|
|
188
|
+
this.estDeconnecteAzure()
|
|
171
189
|
} else {
|
|
172
190
|
this.popupAffiche = false // cookie recréé avec succès, reprendre la surveillance
|
|
173
191
|
}
|
|
@@ -177,28 +195,27 @@ class RafraichisseurToken {
|
|
|
177
195
|
}
|
|
178
196
|
}
|
|
179
197
|
|
|
180
|
-
private estDeconnecteAzure(
|
|
198
|
+
private estDeconnecteAzure(): void {
|
|
181
199
|
//on envoie au portail, pas le choix
|
|
182
|
-
urlPortail = urlPortail.replace(/\/+$/, '')
|
|
183
200
|
const retour = encodeURI(window.location.href)
|
|
184
|
-
|
|
201
|
+
|
|
202
|
+
window.open(`${this.urlPortail}/home/SeConnecter?urlRetour=${retour}`, '_self')
|
|
185
203
|
return
|
|
186
204
|
}
|
|
187
205
|
|
|
188
|
-
public deconnecterPortail(
|
|
189
|
-
|
|
190
|
-
window.location.replace(`${urlPortail}/deconnecte?urlRetour=${encodeURIComponent(window.location.href)}`)
|
|
206
|
+
public deconnecterPortail(): void {
|
|
207
|
+
window.location.replace(`${this.urlPortail}/deconnecte?urlRetour=${encodeURIComponent(window.location.href)}`)
|
|
191
208
|
}
|
|
192
209
|
|
|
193
|
-
private lireCookie(
|
|
210
|
+
private lireCookie(): string | null {
|
|
194
211
|
if (!document.cookie) return null
|
|
195
212
|
const cookies = document.cookie.split(';').map(c => c.trim())
|
|
196
213
|
for (const cookie of cookies) {
|
|
197
|
-
if (cookie.startsWith(`${
|
|
214
|
+
if (cookie.startsWith(`${this.nomTemoin}=`)) {
|
|
198
215
|
try {
|
|
199
|
-
return decodeURIComponent(cookie.substring(
|
|
216
|
+
return decodeURIComponent(cookie.substring(this.nomTemoin.length + 1))
|
|
200
217
|
} catch {
|
|
201
|
-
return cookie.substring(
|
|
218
|
+
return cookie.substring(this.nomTemoin.length + 1)
|
|
202
219
|
}
|
|
203
220
|
}
|
|
204
221
|
}
|
|
@@ -222,11 +239,11 @@ class RafraichisseurToken {
|
|
|
222
239
|
|
|
223
240
|
private reloadSiErreurReseau(): void {
|
|
224
241
|
const CLE = 'rafraichisseur_dernierReload'
|
|
225
|
-
|
|
242
|
+
if (this.loggerTrace) console.log('[RafraichisseurToken] reload si erreur')
|
|
226
243
|
const maintenant = Date.now()
|
|
227
244
|
const dernierReload = Number(sessionStorage.getItem(CLE) ?? 0)
|
|
228
245
|
if (maintenant - dernierReload > 30_000) {
|
|
229
|
-
|
|
246
|
+
if (this.loggerTrace) console.log('[RafraichisseurToken] Écriture sessionStorage:', CLE, maintenant)
|
|
230
247
|
sessionStorage.setItem(CLE, String(maintenant))
|
|
231
248
|
|
|
232
249
|
globalThis.location.reload()
|
|
@@ -236,12 +253,24 @@ class RafraichisseurToken {
|
|
|
236
253
|
}
|
|
237
254
|
|
|
238
255
|
// URL refresh selon env (dev = proxy Vite ; prod = portail)
|
|
239
|
-
private getRefreshUrl(
|
|
256
|
+
private getRefreshUrl(): string {
|
|
240
257
|
if (import.meta.env.MODE === 'development') return '/portail-refresh'
|
|
241
|
-
return urlPortail + '/home/Refresh'
|
|
258
|
+
return this.urlPortail + '/home/Refresh'
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
declare global {
|
|
263
|
+
interface Window {
|
|
264
|
+
rafraichisseurToken: RafraichisseurToken
|
|
242
265
|
}
|
|
243
266
|
}
|
|
244
267
|
|
|
245
268
|
// Instance
|
|
246
269
|
const rafraichisseurToken = new RafraichisseurToken()
|
|
247
270
|
export default rafraichisseurToken
|
|
271
|
+
|
|
272
|
+
declare global {
|
|
273
|
+
interface Window {
|
|
274
|
+
rafraichisseurToken: RafraichisseurToken
|
|
275
|
+
}
|
|
276
|
+
}
|