···11+{ config, lib, pkgs, ... }:
22+33+with lib;
44+55+let
66+77+ cfg = config.programs.i3lock;
88+99+in {
1010+1111+ ###### interface
1212+1313+ options = {
1414+ programs.i3lock = {
1515+ enable = mkEnableOption (mdDoc "i3lock");
1616+ package = mkOption {
1717+ type = types.package;
1818+ default = pkgs.i3lock;
1919+ defaultText = literalExpression "pkgs.i3lock";
2020+ example = literalExpression ''
2121+ pkgs.i3lock-color
2222+ '';
2323+ description = mdDoc ''
2424+ Specify which package to use for the i3lock program,
2525+ The i3lock package must include a i3lock file or link in its out directory in order for the u2fSupport option to work correctly.
2626+ '';
2727+ };
2828+ u2fSupport = mkOption {
2929+ type = types.bool;
3030+ default = false;
3131+ example = true;
3232+ description = mdDoc ''
3333+ Whether to enable U2F support in the i3lock program.
3434+ U2F enables authentication using a hardware device, such as a security key.
3535+ When U2F support is enabled, the i3lock program will set the setuid bit on the i3lock binary and enable the pam u2fAuth service,
3636+ '';
3737+ };
3838+ };
3939+ };
4040+4141+ ###### implementation
4242+4343+ config = mkIf cfg.enable {
4444+4545+ environment.systemPackages = [ cfg.package ];
4646+4747+ security.wrappers.i3lock = mkIf cfg.u2fSupport {
4848+ setuid = true;
4949+ owner = "root";
5050+ group = "root";
5151+ source = "${cfg.package.out}/bin/i3lock";
5252+ };
5353+5454+ security.pam.services.i3lock.u2fAuth = cfg.u2fSupport;
5555+5656+ };
5757+5858+}