Purpose
To protect system from fraud and to improve security policy the password policy must be improved.
Functional requirement
1. Complexity Validation
Validate complexity of user's password
- has at least 12 characters long;
- contains both upper- and lowercase letter and numbers (required), special characters (optional)
Must be controlled by regular expression: ^(?=.*[a-z][а-яёїієґ])(?=.*[A-ZА-ЯЁЇIЄҐ])(?=.*\d)
- Validate upper, lowercase letter and numbers
In case of error - return 422 error (message: "Password does not meet complexity requirements")
{:error, [{%{ description: "Password does not meet complexity requirements", params: [], rule: :invalid }, "$.password"}]}
- 2. Validate password length (at least 12 characters long)
In case of error - return 422 error (message: "Password must be at least 12 characters long")
{:error, [{%{ description: "Password must be at least 12 characters long", params: [], rule: :invalid }, "$.password"}]}
- Add to mithril.users password_expires_at = now()+config.password_lifetime
2. Save passwords history
When $.decrypted_hash<>mihril.users.password (the user set up a new password) - add the row to mithril.user_passwords_history
Destination | Source | Description |
---|---|---|
id | Autogenerated | |
user_id | $.user_id | Extract user from token |
password | $.decrypted_hash | |
inserted_at | Timestamp: now() | Get current date-time |
3. Not allow to use recently used passwords
While setting up a new password compare it with 3 previous passwords (saved decrypted_hash from mithril.user_passwords_history)
- If $.decrypted_hash=mithril.user_passwords_history.password return 422 error (message: "This password has been used recently. Try another one")
{:error, [{%{ description: "This password has been used recently. Try another one", params: [], rule: :invalid }, "$.password"}]}
4. Remind to change passwords
- Each time when user login into system check condition:
- now()<=mithril.users.password_expires_at-config.password_to_change
- if condition=false
- show message 'Your passwords expires soon. Please, change it to the new one.'
5. Expire Passwords
Fetch all records from mithril.users where now()>=mithril.users.password_expires_at
- set expires_at=now() for all tokens where tokens.user_id=$user.id (--and tokens.name='refresh_token')
- don't send access_token in response on {{
host}}/
oauth/tokens until the password will be changed. Show the message "The password must be changed".