Two options, the proper way would probably be to develop an add-on. Myself being too rusty on my PHP I think I might be tempted to just prod the database. So the password update date is stored in
xf_user_profile, if it's never been changed then it's set to 1 (ie one second past the epoch), otherwise it's a timestamp for the last change date/time. The security lock setting is in the
xf_user table and is a enum. So you could do a query based on the current time and the last changed password time and change the security lock based on that.
So if I were doing it all in one SQL query and bodging it via a daily cron job or something I'd do:
SQL:
update xf_user join xf_user_profile on xf_user.user_id = xf_user_profile.user_id set xf_user.security_lock = 'change' where timestampdiff(day, from_unixtime(xf_user_profile.password_date), now()) > 60 and xf_user_profile.password_date != 1;
Which should require anyone whose last password change was over 60 days ago to change their password. Of course they can change their password to what it currently is! In the above SQL I have excluded those password that have never been changed. I'm guessing those will either be ones setup on install or might be the case when users are using other authentication mechanisms. I don't know since I've only literally just looked at this now. The query was run on a MySQL 5.7 database, MySQL 8 also has a
datediff() function (although
timestampdiff() is still present) and other databases will no doubt have similar. You don't have to use days you can do other time periods (see the docs).
Breaking it down so it's a bit more visible:
SQL:
update xf_user
join xf_user_profile on xf_user.user_id = xf_user_profile.user_id
set xf_user.security_lock = 'change'
where
timestampdiff(day, from_unixtime(xf_user_profile.password_date), now()) > 60
and
xf_user_profile.password_date != 1;
We're joining the
xf_user_profile and
xf_user tables to provide us with all the data we need and setting the
security_lock value in the
xf_user table where the difference between "
now" and the
password_date is more than 60 days and the
password_date isn't set to 1.
If you want to have a play with a less destructive version and see what data you get out here is a
select instead of an
update:
SQL:
select xf_user.user_id,xf_user.username,from_unixtime(xf_user_profile.password_date) as "password last changed" from xf_user join xf_user_profile on xf_user.user_id = xf_user_profile.user_id where timestampdiff(day, from_unixtime(xf_user_profile.password_date), now()) > 60 and xf_user_profile.password_date != 1;
Anyhow hope that might help you somewhat.