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 {
|
||||
sequence: "Ctrl+Q"
|
||||
onActivated: Qt.quit()
|
||||
@@ -85,13 +143,16 @@ Kirigami.ApplicationWindow {
|
||||
|
||||
component SecretField: Controls.TextField {
|
||||
id: field
|
||||
|
||||
property bool secretVisible: false
|
||||
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: 50
|
||||
echoMode: TextInput.Password
|
||||
echoMode: secretVisible ? TextInput.Normal : TextInput.Password
|
||||
passwordCharacter: "●"
|
||||
font.pixelSize: 15
|
||||
leftPadding: 16
|
||||
rightPadding: 16
|
||||
rightPadding: 56
|
||||
selectByMouse: true
|
||||
|
||||
background: Rectangle {
|
||||
@@ -100,6 +161,39 @@ Kirigami.ApplicationWindow {
|
||||
border.width: field.activeFocus ? 2 : 1
|
||||
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 {
|
||||
@@ -575,6 +669,84 @@ Kirigami.ApplicationWindow {
|
||||
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 {
|
||||
text: "Confirmation"
|
||||
color: "#334155"
|
||||
|
||||
Reference in New Issue
Block a user