codevdesign 1.0.0 → 1.0.2
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/csqcChaise/chaiseConteneur.vue +363 -363
- package/composants/csqcRechercheUtilisateur.vue +197 -197
- package/composants/gabarit/pivEntete.vue +14 -1
- package/index.ts +72 -72
- package/outils/appAxios.ts +1 -2
- package/outils/rafraichisseurToken.ts +47 -29
- package/package.json +2 -2
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import i18n from '@/plugins/i18n'
|
|
2
1
|
import { useAppStore } from '@/store/appStore'
|
|
3
2
|
|
|
4
3
|
class RafraichisseurToken {
|
|
@@ -8,14 +7,15 @@ class RafraichisseurToken {
|
|
|
8
7
|
private popupAffiche = false
|
|
9
8
|
private appStore: ReturnType<typeof useAppStore> | null = null
|
|
10
9
|
private timerId: number | null = null
|
|
11
|
-
private deconnexionEnCours = false // évite les popups multiples
|
|
12
10
|
|
|
13
11
|
// Lance une seule fois
|
|
14
12
|
public async demarrer(): Promise<void> {
|
|
15
13
|
this.appStore = useAppStore()
|
|
16
14
|
await this.verifierToken()
|
|
17
15
|
if (this.timerId != null) return
|
|
18
|
-
this.timerId = window.setInterval(() => {
|
|
16
|
+
this.timerId = window.setInterval(() => {
|
|
17
|
+
this.verifierToken()
|
|
18
|
+
}, this.intervalleEnSecondes * 1000)
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
// Permet d’arrêter le timer (ex: au logout / destroy)
|
|
@@ -31,7 +31,10 @@ class RafraichisseurToken {
|
|
|
31
31
|
const modele = this.appStore?.appModele
|
|
32
32
|
if (this.popupAffiche || !modele) return
|
|
33
33
|
const tokenEncode = this.lireCookie(modele.nomCookie)
|
|
34
|
-
if (!tokenEncode) {
|
|
34
|
+
if (!tokenEncode) {
|
|
35
|
+
await this.rafraichir()
|
|
36
|
+
return
|
|
37
|
+
}
|
|
35
38
|
|
|
36
39
|
let token: any
|
|
37
40
|
try {
|
|
@@ -42,7 +45,8 @@ class RafraichisseurToken {
|
|
|
42
45
|
}
|
|
43
46
|
|
|
44
47
|
const exp = Number(token?.exp)
|
|
45
|
-
if (!Number.isFinite(exp)) {
|
|
48
|
+
if (!Number.isFinite(exp)) {
|
|
49
|
+
// exp manquant/invalide → tente refresh
|
|
46
50
|
await this.rafraichir()
|
|
47
51
|
return
|
|
48
52
|
}
|
|
@@ -63,6 +67,7 @@ class RafraichisseurToken {
|
|
|
63
67
|
const timeout = setTimeout(() => controller.abort(), 10_000)
|
|
64
68
|
|
|
65
69
|
try {
|
|
70
|
+
//Première tentative sans iframe, pour la majorité des cas.
|
|
66
71
|
const resp = await fetch(url, {
|
|
67
72
|
method: 'POST',
|
|
68
73
|
credentials: 'include',
|
|
@@ -72,21 +77,22 @@ class RafraichisseurToken {
|
|
|
72
77
|
})
|
|
73
78
|
|
|
74
79
|
// redirection (souvent => login) → traiter comme non auth
|
|
80
|
+
|
|
75
81
|
if (resp.type === 'opaqueredirect' || resp.status === 302) {
|
|
76
|
-
this.
|
|
82
|
+
this.rafraichirParIframe()
|
|
77
83
|
return
|
|
78
84
|
}
|
|
79
85
|
|
|
80
86
|
// OK ou No Content: le cookie devrait être réécrit
|
|
81
87
|
if (resp.status === 200 || resp.status === 204) {
|
|
82
88
|
const jeton = this.lireCookie(modele.nomCookie)
|
|
83
|
-
if (!jeton) this.
|
|
89
|
+
if (!jeton) this.rafraichirParIframe()
|
|
84
90
|
return
|
|
85
91
|
}
|
|
86
92
|
|
|
87
93
|
// non auth / expiré (401, 419) + IIS timeout (440)
|
|
88
94
|
if (resp.status === 401 || resp.status === 419 || resp.status === 440) {
|
|
89
|
-
this.
|
|
95
|
+
this.rafraichirParIframe()
|
|
90
96
|
return
|
|
91
97
|
}
|
|
92
98
|
|
|
@@ -100,20 +106,32 @@ class RafraichisseurToken {
|
|
|
100
106
|
}
|
|
101
107
|
}
|
|
102
108
|
|
|
103
|
-
private
|
|
104
|
-
if (this.deconnexionEnCours) return
|
|
105
|
-
this.deconnexionEnCours = true
|
|
106
|
-
const { t } = i18n.global
|
|
107
|
-
this.popupAffiche = true
|
|
109
|
+
private rafraichirParIframe() {
|
|
108
110
|
if (!this.appStore) this.appStore = useAppStore()
|
|
111
|
+
// 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é
|
|
112
|
+
// ajax vers le refresh
|
|
113
|
+
let iframe = document.createElement('iframe')
|
|
114
|
+
iframe.src = `${this.appStore.appModele!.urlPortailRafraichissement}?urlRetour=${encodeURI(window.localStorage.href)}`
|
|
115
|
+
iframe.id = 'idRafrToken'
|
|
116
|
+
iframe.style.display = 'none'
|
|
117
|
+
document.body.appendChild(iframe)
|
|
118
|
+
iframe.onload = () => {
|
|
119
|
+
const jetonCSQC = this.lireCookie(this.appStore!.appModele!.nomCookie)
|
|
120
|
+
if (jetonCSQC == null || jetonCSQC === '') {
|
|
121
|
+
this.estDeconnecteAzure()
|
|
122
|
+
}
|
|
109
123
|
|
|
110
|
-
|
|
111
|
-
const retour = encodeURI(window.location.href)
|
|
112
|
-
window.open(`${this.appStore.appModele.urlPortailSeConnecter}?urlRetour=${retour}`, '_self')
|
|
124
|
+
iframe.remove()
|
|
113
125
|
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
private estDeconnecteAzure(): void {
|
|
129
|
+
//on envoie au portail, pas le choix
|
|
130
|
+
if (!this.appStore) this.appStore = useAppStore()
|
|
114
131
|
|
|
115
|
-
|
|
116
|
-
this.
|
|
132
|
+
const retour = encodeURI(window.location.href)
|
|
133
|
+
window.open(`${this.appStore.appModele!.urlPortailSeConnecter}?urlRetour=${retour}`, '_self')
|
|
134
|
+
return
|
|
117
135
|
}
|
|
118
136
|
|
|
119
137
|
public deconnecterPortail(): void {
|
|
@@ -121,23 +139,20 @@ class RafraichisseurToken {
|
|
|
121
139
|
const modele = this.appStore?.appModele
|
|
122
140
|
if (!modele) return
|
|
123
141
|
|
|
124
|
-
window.location.replace(
|
|
125
|
-
`${modele.urlPortail}deconnecte?urlRetour=${encodeURIComponent(window.location.href)}`
|
|
126
|
-
)
|
|
142
|
+
window.location.replace(`${modele.urlPortail}deconnecte?urlRetour=${encodeURIComponent(window.location.href)}`)
|
|
127
143
|
}
|
|
128
144
|
|
|
129
|
-
public annulerDeconnecter(): void {
|
|
130
|
-
this.popupAffiche = false
|
|
131
|
-
this.deconnexionEnCours = false
|
|
132
|
-
}
|
|
133
145
|
|
|
134
146
|
private lireCookie(nom: string): string | null {
|
|
135
147
|
if (!document.cookie) return null
|
|
136
148
|
const cookies = document.cookie.split(';').map(c => c.trim())
|
|
137
149
|
for (const cookie of cookies) {
|
|
138
150
|
if (cookie.startsWith(`${nom}=`)) {
|
|
139
|
-
try {
|
|
140
|
-
|
|
151
|
+
try {
|
|
152
|
+
return decodeURIComponent(cookie.substring(nom.length + 1))
|
|
153
|
+
} catch {
|
|
154
|
+
return cookie.substring(nom.length + 1)
|
|
155
|
+
}
|
|
141
156
|
}
|
|
142
157
|
}
|
|
143
158
|
return null
|
|
@@ -150,14 +165,17 @@ class RafraichisseurToken {
|
|
|
150
165
|
if (!base64Url) throw new Error('Invalid JWT format')
|
|
151
166
|
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/')
|
|
152
167
|
const jsonPayload = decodeURIComponent(
|
|
153
|
-
atob(base64)
|
|
168
|
+
atob(base64)
|
|
169
|
+
.split('')
|
|
170
|
+
.map(c => `%${`00${c.charCodeAt(0).toString(16)}`.slice(-2)}`)
|
|
171
|
+
.join(''),
|
|
154
172
|
)
|
|
155
173
|
return JSON.parse(jsonPayload)
|
|
156
174
|
}
|
|
157
175
|
|
|
158
176
|
// URL refresh selon env (dev = proxy Vite ; prod = portail)
|
|
159
177
|
private getRefreshUrl(): string {
|
|
160
|
-
if (import.meta.env.MODE ===
|
|
178
|
+
if (import.meta.env.MODE === 'development') return '/portail-refresh'
|
|
161
179
|
return this.appStore!.appModele!.urlPortailRafraichissement
|
|
162
180
|
}
|
|
163
181
|
}
|
package/package.json
CHANGED