Téléverser les fichiers vers "first-login-ui/src"
This commit is contained in:
+174
-2
@@ -31,6 +31,64 @@ Kirigami.ApplicationWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Indicateur volontairement informatif : il ne bloque jamais
|
||||||
|
// la validation du mot de passe. La longueur est privilégiée,
|
||||||
|
// la diversité des caractères apporte un bonus visuel.
|
||||||
|
function passwordStrengthLevel(password) {
|
||||||
|
if (password.length === 0)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
var classes = 0
|
||||||
|
if (/[a-z]/.test(password)) classes += 1
|
||||||
|
if (/[A-Z]/.test(password)) classes += 1
|
||||||
|
if (/[0-9]/.test(password)) classes += 1
|
||||||
|
if (/[^A-Za-z0-9]/.test(password)) classes += 1
|
||||||
|
|
||||||
|
var level = 1
|
||||||
|
|
||||||
|
if (password.length >= 16)
|
||||||
|
level = classes >= 2 ? 4 : 3
|
||||||
|
else if (password.length >= 12)
|
||||||
|
level = classes >= 2 ? 3 : 2
|
||||||
|
else if (password.length >= 8)
|
||||||
|
level = classes >= 3 ? 2 : 1
|
||||||
|
|
||||||
|
// Quelques motifs manifestement faibles : on réduit
|
||||||
|
// l'indication sans empêcher l'utilisateur de continuer.
|
||||||
|
var lower = password.toLowerCase()
|
||||||
|
if (lower === "password" || lower === "motdepasse" ||
|
||||||
|
lower === "azerty" || lower === "qwerty" ||
|
||||||
|
lower === "12345678" || /^(.)\1+$/.test(password)) {
|
||||||
|
level = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
return level
|
||||||
|
}
|
||||||
|
|
||||||
|
function passwordStrengthLabel(level) {
|
||||||
|
if (level === 1) return "Faible"
|
||||||
|
if (level === 2) return "Moyen"
|
||||||
|
if (level === 3) return "Bon"
|
||||||
|
if (level === 4) return "Très bon"
|
||||||
|
return "Non évalué"
|
||||||
|
}
|
||||||
|
|
||||||
|
function passwordStrengthColor(level) {
|
||||||
|
if (level === 1) return "#dc2626"
|
||||||
|
if (level === 2) return "#d97706"
|
||||||
|
if (level === 3) return "#2563eb"
|
||||||
|
if (level === 4) return "#16a34a"
|
||||||
|
return "#cbd5e1"
|
||||||
|
}
|
||||||
|
|
||||||
|
function passwordStrengthHint(level) {
|
||||||
|
if (level === 1) return "Privilégiez surtout la longueur : une phrase de passe de 12 caractères ou plus est un bon point de départ."
|
||||||
|
if (level === 2) return "Correct pour un usage courant, mais quelques caractères supplémentaires amélioreraient sensiblement la robustesse."
|
||||||
|
if (level === 3) return "Bonne robustesse apparente : la longueur et la diversité sont satisfaisantes."
|
||||||
|
if (level === 4) return "Très bonne robustesse apparente : mot de passe long et suffisamment diversifié."
|
||||||
|
return "Saisissez votre nouveau mot de passe pour obtenir une indication de robustesse."
|
||||||
|
}
|
||||||
|
|
||||||
Shortcut {
|
Shortcut {
|
||||||
sequence: "Ctrl+Q"
|
sequence: "Ctrl+Q"
|
||||||
onActivated: Qt.quit()
|
onActivated: Qt.quit()
|
||||||
@@ -85,13 +143,16 @@ Kirigami.ApplicationWindow {
|
|||||||
|
|
||||||
component SecretField: Controls.TextField {
|
component SecretField: Controls.TextField {
|
||||||
id: field
|
id: field
|
||||||
|
|
||||||
|
property bool secretVisible: false
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
implicitHeight: 50
|
implicitHeight: 50
|
||||||
echoMode: TextInput.Password
|
echoMode: secretVisible ? TextInput.Normal : TextInput.Password
|
||||||
passwordCharacter: "●"
|
passwordCharacter: "●"
|
||||||
font.pixelSize: 15
|
font.pixelSize: 15
|
||||||
leftPadding: 16
|
leftPadding: 16
|
||||||
rightPadding: 16
|
rightPadding: 56
|
||||||
selectByMouse: true
|
selectByMouse: true
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
@@ -100,6 +161,39 @@ Kirigami.ApplicationWindow {
|
|||||||
border.width: field.activeFocus ? 2 : 1
|
border.width: field.activeFocus ? 2 : 1
|
||||||
border.color: field.activeFocus ? "#2563eb" : "#cbd5e1"
|
border.color: field.activeFocus ? "#2563eb" : "#cbd5e1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Controls.ToolButton {
|
||||||
|
id: visibilityButton
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 8
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
width: 38
|
||||||
|
height: 38
|
||||||
|
|
||||||
|
hoverEnabled: true
|
||||||
|
focusPolicy: Qt.NoFocus
|
||||||
|
Accessible.name: field.secretVisible ? "Masquer la valeur" : "Afficher la valeur"
|
||||||
|
|
||||||
|
onClicked: field.secretVisible = !field.secretVisible
|
||||||
|
|
||||||
|
contentItem: Kirigami.Icon {
|
||||||
|
source: field.secretVisible ? "view-hidden" : "view-visible"
|
||||||
|
implicitWidth: 20
|
||||||
|
implicitHeight: 20
|
||||||
|
color: visibilityButton.hovered ? "#2563eb" : "#64748b"
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
radius: 8
|
||||||
|
color: visibilityButton.pressed ? "#dbeafe"
|
||||||
|
: visibilityButton.hovered ? "#eff6ff"
|
||||||
|
: "transparent"
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation { duration: 100 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
component StepDot: Rectangle {
|
component StepDot: Rectangle {
|
||||||
@@ -575,6 +669,84 @@ Kirigami.ApplicationWindow {
|
|||||||
placeholderText: "Choisissez votre mot de passe personnel"
|
placeholderText: "Choisissez votre mot de passe personnel"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Indicateur de robustesse purement informatif.
|
||||||
|
// Il ne participe pas à la condition d'activation
|
||||||
|
// du bouton Continuer.
|
||||||
|
Rectangle {
|
||||||
|
id: strengthCard
|
||||||
|
Layout.fillWidth: true
|
||||||
|
implicitHeight: 112
|
||||||
|
radius: 12
|
||||||
|
color: "#f8fafc"
|
||||||
|
border.width: 1
|
||||||
|
border.color: "#e2e8f0"
|
||||||
|
|
||||||
|
property int strengthLevel: root.passwordStrengthLevel(newPassword.text)
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 14
|
||||||
|
spacing: 8
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
Controls.Label {
|
||||||
|
text: "Robustesse du mot de passe"
|
||||||
|
color: "#334155"
|
||||||
|
font.pixelSize: 12
|
||||||
|
font.weight: Font.DemiBold
|
||||||
|
}
|
||||||
|
|
||||||
|
Item { Layout.fillWidth: true }
|
||||||
|
|
||||||
|
Controls.Label {
|
||||||
|
text: root.passwordStrengthLabel(strengthCard.strengthLevel)
|
||||||
|
color: root.passwordStrengthColor(strengthCard.strengthLevel)
|
||||||
|
font.pixelSize: 12
|
||||||
|
font.weight: Font.Bold
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: 6
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: 4
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
required property int index
|
||||||
|
Layout.fillWidth: true
|
||||||
|
implicitHeight: 7
|
||||||
|
radius: 4
|
||||||
|
color: index < parent.parent.parent.strengthLevel
|
||||||
|
? root.passwordStrengthColor(strengthCard.strengthLevel)
|
||||||
|
: "#e2e8f0"
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation { duration: 140 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Controls.Label {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: root.passwordStrengthHint(strengthCard.strengthLevel)
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
color: "#64748b"
|
||||||
|
font.pixelSize: 11
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Controls.Label {
|
||||||
|
text: "Indication uniquement : un mot de passe faible n'est pas bloqué."
|
||||||
|
color: "#94a3b8"
|
||||||
|
font.pixelSize: 11
|
||||||
|
}
|
||||||
|
|
||||||
Controls.Label {
|
Controls.Label {
|
||||||
text: "Confirmation"
|
text: "Confirmation"
|
||||||
color: "#334155"
|
color: "#334155"
|
||||||
|
|||||||
Reference in New Issue
Block a user