mirror of
https://github.com/nmasur/dotfiles
synced 2026-07-29 08:18:34 +00:00
add actualtap for working with actual api
This commit is contained in:
@@ -159,6 +159,7 @@ lib
|
|||||||
inputs.wsl.nixosModules.wsl
|
inputs.wsl.nixosModules.wsl
|
||||||
{ imports = (nixFiles ../platforms/nixos); }
|
{ imports = (nixFiles ../platforms/nixos); }
|
||||||
module
|
module
|
||||||
|
# (builtins.removeAttrs module [ "home-manager" ])
|
||||||
{
|
{
|
||||||
home-manager = {
|
home-manager = {
|
||||||
extraSpecialArgs = {
|
extraSpecialArgs = {
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
buildNpmPackage,
|
||||||
|
fetchFromGitHub,
|
||||||
|
nodejs,
|
||||||
|
}:
|
||||||
|
|
||||||
|
buildNpmPackage rec {
|
||||||
|
pname = "actualtap";
|
||||||
|
version = "1.0.34";
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "MattFaz";
|
||||||
|
repo = "actualtap";
|
||||||
|
rev = "v${version}";
|
||||||
|
hash = "sha256-I2yb3WCOXYx/6RXiKjePlpChrr9G1il44OdON/SeVCw=";
|
||||||
|
};
|
||||||
|
|
||||||
|
npmDepsHash = "sha256-LlTLwUt0Yja4NSBLbaYPV/keawSJKffno/28rtSj/oQ=";
|
||||||
|
|
||||||
|
dontNpmBuild = true;
|
||||||
|
|
||||||
|
postPatch = ''
|
||||||
|
substituteInPlace src/server.js \
|
||||||
|
--replace-fail 'port: 3001' 'port: process.env.PORT || 3001'
|
||||||
|
'';
|
||||||
|
|
||||||
|
postInstall = ''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
cat <<EOF > $out/bin/actualtap
|
||||||
|
#!/bin/sh
|
||||||
|
exec ${lib.getExe nodejs} $out/lib/node_modules/actualtap/src/server.js "\$@"
|
||||||
|
EOF
|
||||||
|
chmod +x $out/bin/actualtap
|
||||||
|
'';
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "Automatically create transactions in Actual Budget when you use Tap-to-Pay on a mobile device";
|
||||||
|
homepage = "https://github.com/MattFaz/actualtap";
|
||||||
|
license = licenses.gpl3Only;
|
||||||
|
maintainers = [ ];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -109,8 +109,9 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
# Allow web traffic to Caddy
|
# Allow web traffic to Caddy
|
||||||
nmasur.presets.services.caddy.routes = [
|
nmasur.presets.services.caddy.routes = lib.mkAfter [
|
||||||
{
|
{
|
||||||
|
group = "actual";
|
||||||
match = [ { host = [ hostnames.budget ]; } ];
|
match = [ { host = [ hostnames.budget ]; } ];
|
||||||
handle = [
|
handle = [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,122 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
inherit (config.nmasur.settings) hostnames;
|
||||||
|
cfg = config.nmasur.presets.services.actualtap;
|
||||||
|
|
||||||
|
actualtapConfigType = lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
port = lib.mkOption {
|
||||||
|
type = lib.types.port;
|
||||||
|
description = "Port to use for the actualtap instance localhost";
|
||||||
|
};
|
||||||
|
path = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "Path prefix for this actualtap instance on the reverse proxy";
|
||||||
|
};
|
||||||
|
budgetIdFile = lib.mkOption {
|
||||||
|
type = lib.types.path;
|
||||||
|
description = "Path to the age encrypted file containing the budget ID";
|
||||||
|
};
|
||||||
|
apiKeyFile = lib.mkOption {
|
||||||
|
type = lib.types.path;
|
||||||
|
description = "Path to the age encrypted file containing the API key";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
options.nmasur.presets.services.actualtap = {
|
||||||
|
enable = lib.mkEnableOption "ActualTap instances";
|
||||||
|
instances = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf actualtapConfigType;
|
||||||
|
default = { };
|
||||||
|
description = "Attribute set of ActualTap instances.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
|
||||||
|
users.users.actualtap = {
|
||||||
|
isSystemUser = true;
|
||||||
|
group = "shared";
|
||||||
|
uid = 981;
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services = lib.mapAttrs' (
|
||||||
|
name: instance:
|
||||||
|
lib.nameValuePair "actualtap-${name}" {
|
||||||
|
enable = true;
|
||||||
|
description = "ActualTap - ${name}";
|
||||||
|
after = [
|
||||||
|
"network.target"
|
||||||
|
"actual.service"
|
||||||
|
];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
|
environment = {
|
||||||
|
PORT = builtins.toString instance.port;
|
||||||
|
ACTUAL_URL = "http://127.0.0.1:${builtins.toString config.nmasur.presets.services.actualbudget.port}";
|
||||||
|
};
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
User = config.users.users.actualtap.name;
|
||||||
|
Group = config.users.users.actualtap.group;
|
||||||
|
EnvironmentFile = [
|
||||||
|
config.secrets."actualbudget-password".dest
|
||||||
|
config.secrets."actualtap-${name}-budget-id".dest
|
||||||
|
config.secrets."actualtap-${name}-api-key".dest
|
||||||
|
];
|
||||||
|
ExecStart = lib.getExe pkgs.nmasur.actualtap;
|
||||||
|
Restart = "on-failure";
|
||||||
|
WorkingDirectory = "/var/lib/actualtap-${name}";
|
||||||
|
StateDirectory = "actualtap-${name}";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
) cfg.instances;
|
||||||
|
|
||||||
|
secrets = lib.mkMerge (
|
||||||
|
lib.mapAttrsToList (name: instance: {
|
||||||
|
"actualtap-${name}-budget-id" = {
|
||||||
|
source = instance.budgetIdFile;
|
||||||
|
dest = "${config.secretsDirectory}/actualtap-${name}-budget-id";
|
||||||
|
owner = config.users.users.actualtap.name;
|
||||||
|
group = config.users.users.actualtap.group;
|
||||||
|
};
|
||||||
|
"actualtap-${name}-api-key" = {
|
||||||
|
source = instance.apiKeyFile;
|
||||||
|
dest = "${config.secretsDirectory}/actualtap-${name}-api-key";
|
||||||
|
owner = config.users.users.actualtap.name;
|
||||||
|
group = config.users.users.actualtap.group;
|
||||||
|
};
|
||||||
|
}) cfg.instances
|
||||||
|
);
|
||||||
|
|
||||||
|
nmasur.presets.services.caddy.routes = lib.mapAttrsToList (name: instance: {
|
||||||
|
group = "actual";
|
||||||
|
match = [
|
||||||
|
{
|
||||||
|
host = [ hostnames.budget ];
|
||||||
|
path = [ "${instance.path}*" ];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
handle = [
|
||||||
|
{
|
||||||
|
handler = "rewrite";
|
||||||
|
strip_path_prefix = instance.path;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
handler = "reverse_proxy";
|
||||||
|
upstreams = [ { dial = "localhost:${builtins.toString instance.port}"; } ];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}) cfg.instances;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IE1nSGFPdyBIUkxs
|
||||||
|
RmFmNmo3L2MwVVhmeTdUVGdXOWRIVDd5c21EVnhtWWUwTVpWbW5zCnNSS1luUHNW
|
||||||
|
YlIwbmVrbTJTUUdOQkpCbGpNQm1tYlRrbDhaWEhJUDRHaDQKLT4gc3NoLWVkMjU1
|
||||||
|
MTkgWXlTVU1RIHJIYTd4eFo3aklGQ1Evb0JPOGZSWDh1Q1pXU3ExZ1pmR29qT2lP
|
||||||
|
bFcwREkKTWFXMlZCeXpoMi92OXdtN3plekE2dFlCbk44YncxLzJYZzE2amNIVnEz
|
||||||
|
QQotPiBzc2gtZWQyNTUxOSBuanZYNUEgWi8rNnV4VWtwUEEzbys4Skl1Z0p0Ly9r
|
||||||
|
ZS82dzFJeEhHVHpSNU04WU5CVQpIMWhQcDdNeU45dVpkVyswQW1RK2Q0aXpkZXMz
|
||||||
|
MXAraG9KUFBDUVdFcTRVCi0+IHNzaC1lZDI1NTE5IENxSU9VQSBUQWQvU0JwdTlX
|
||||||
|
UkJYakdYTjU1YlBzWHEzY3FQa1dhMmp6UjE0RTJYN1ZBCmk0SWc0Ym1mUTdVL1NJ
|
||||||
|
ZXJFVkNmckRaVnlkSmUxL0dSUlo5VER0b2x3WVUKLT4gc3NoLWVkMjU1MTkgejFP
|
||||||
|
Y1p3IHBIQllKcmczOVJvSzRMZW9mVjZjTFo1ZjVJNDRvUG9pSnlRZDBUWEtoV2sK
|
||||||
|
aGhPeUpkVEZ0QWxDM1VJZzlDWEZ2VnFuTFRCVDkzY2JLVWNQTUE2STMyRQotLS0g
|
||||||
|
cXhWR2lQWnkxOUZhRzhOTS96UDJWVmZEQVpZTkF1MmlpNCtEbDZzRGZaYwof4Y/t
|
||||||
|
N5osO/bY+ojbarYoCBq12NSaKKlL6MNy1OQZOuOF0IP1CZ0fLY+R9DgJcNol3I73
|
||||||
|
q4JyXbfohWtG/2NdIwhRXumQ/OnY1maVvg==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IE1nSGFPdyAyRTF0
|
||||||
|
L3Y3ZVJ0YlJSbzR6cnNWeVNRd2czNUVKWmtQNFA3VFRlb053d1dRCmxmTGRGSFhL
|
||||||
|
UmlSdUVQNzVPcktIdE0yVWFhVGpGYVRPMEpNQll6Z0owNFEKLT4gc3NoLWVkMjU1
|
||||||
|
MTkgWXlTVU1RIHE5L09YNWFaT0JLT0o0YjdQY01GRDByeFVXeE9LMXNFNGFCWkFO
|
||||||
|
ZStBd28KamhUYzd1VXhlL3RqY3hlMG5UeGFJemY2ajRhVGZ2ZDJNb1hSRHkrUFNt
|
||||||
|
NAotPiBzc2gtZWQyNTUxOSBuanZYNUEgbDdMVzNTT1Y2VmVsZyt2WTh0RWdUVEpY
|
||||||
|
c0RoRWE2S2ZyZXFuTllFU1FVWQpmeDF0MEp2NEYxS2k1ZlJaTVNWMWdRRlJ1UWh2
|
||||||
|
Wm0xbHhGYXhoWGtDbVkwCi0+IHNzaC1lZDI1NTE5IENxSU9VQSBJeERSTUpPbzhu
|
||||||
|
NGQrZXRoWGJEalBlMHdQUmlsVkF2TEZBOStOZ3ExN2lzClRZeE5yZG1uY3ZRRDNy
|
||||||
|
am5uTjRiTnpLSkhURWZTNzgyVVdOVDA2WlpqZmsKLT4gc3NoLWVkMjU1MTkgejFP
|
||||||
|
Y1p3IGticUNqWDJ0RTJTZmdXdzVWM0xsejBvYUJ3MXZvNWw1OWE3aUJMTCtSQ2MK
|
||||||
|
KzMyZW5jZUNIV1puVFlLMEdyeUdoUUt3MjlzTUgvWlFob0QwME9ZZ1VVNAotLS0g
|
||||||
|
VU5nOFA0Nzd3ckhnRHdSNkVSNG9tZks5VmVoZnlmU1R6bzl4ZVdMcGlLTQqZWLkP
|
||||||
|
VdZPvgCJ8A9UcKWl+5f8Jjlc79d6ib8wwfMRl0zK4SNQJGgcXr6sFuieY3H4DzRb
|
||||||
|
MuqKZQBBIKtPAmrvmzcKgNSeiJoZjG801Jqd3lpkJEA=
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IE1nSGFPdyBSR2tx
|
||||||
|
b2FyZ2t0d2xONGIvYjJrcVU1VTNHT3RVbjlWT1IyUW1CM1BkNVNzCmJmNFFFbUR6
|
||||||
|
WG9ncmhuakFzVHhSVEtZUlR4dWg3cWRzUXc2ZmVpZ3NqZ1EKLT4gc3NoLWVkMjU1
|
||||||
|
MTkgWXlTVU1RIGFFRmFsVjdkTkFZY29XdWo4akVDaEZHMTdXRDY4N2U5WE13a1JD
|
||||||
|
QWdXMkUKbnVXazZpSzZqTHJqamFUdDJMMUpiTEhLeTJqcVNmV2dncjVvZlNNT09M
|
||||||
|
WQotPiBzc2gtZWQyNTUxOSBuanZYNUEgTzV0eGpSU2plaTFCTXZTbFB2R1VOQnFn
|
||||||
|
d01EUXcza3JuR3RFUzE3N2MzawpqT0ZRQ1hPTFcvZ2ZOQjNGcThYL1lSdURXbWlv
|
||||||
|
NkRSRERJQ1IvSHdMa2M4Ci0+IHNzaC1lZDI1NTE5IENxSU9VQSBvQjZkYVJjYy9H
|
||||||
|
L3BSVWRPczlOOGV2RkRBSGlIakF1cG1yQk9tbXNWdWlZCnZGaGxvdkZVWXp2THhK
|
||||||
|
RnRBQ2VSNkErU0VnOWlYbkY2U1JCZTlBSFFUK0UKLT4gc3NoLWVkMjU1MTkgejFP
|
||||||
|
Y1p3IFQrdUtDdENRK2dnN2t3dVBsN0oxYkNRSm43aDREa3ZJQjhvTWpxM0FWVEkK
|
||||||
|
OTNCVFRTclFFckFkQXBzWnBybWxKRm92TEFqRU5ZWkprdytJQm5RT2tOYwotLS0g
|
||||||
|
Nk5WZXhZM0VXaHpVK2EzeGFqNS9hZUlLQjlJRU9EMnVLL3VRV3RKTkVRcwpA8GqA
|
||||||
|
24oLFT1VIE5eNl/Ltd102W4J6jafmiizCEu3/7EULI/X5oh2LvjSjOuivW6y+Gbu
|
||||||
|
rXITu245mDM6ZqE2LikYR6134QSC2lmNvw==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IE1nSGFPdyAyakVC
|
||||||
|
ZGZqMitTVVc0KzJSV0c3V3Ryc2JSWXp0V2I4YURmektyVGh5a2hBCjlCaGQ4SmxQ
|
||||||
|
VzhBRWw4SW9QamdVZDVvK3laVkNuWTRhMW1hR1ZmS1lqOWsKLT4gc3NoLWVkMjU1
|
||||||
|
MTkgWXlTVU1RIE5oVVdMWHZlSEJ2akc1UVcrdnNNOWgzaGFhb2VWNlNxQU5yQzM0
|
||||||
|
dGk3eGsKaE1Ba3BneC9yQTBpcXo3YWhqcDZheUJnbE5vS0Z0WUNzYnQ1a2o5OVN4
|
||||||
|
YwotPiBzc2gtZWQyNTUxOSBuanZYNUEgcitOTmNKS04xc01LNTZKbE9QblVKRUVr
|
||||||
|
ZHdyY0Q2VWtUQ1VOQnFZTjNpbwp0RmNTV2RwR2RlcG5odE81VEFxNGhJOVFYd3Zk
|
||||||
|
TU9IanIzMFkxVU1GUlQwCi0+IHNzaC1lZDI1NTE5IENxSU9VQSBmRC92WjRkTVFz
|
||||||
|
eGlFa1VhcEk1NVpkVnFVVkpZRTdzMGR1aWNuWW9ZTFFVCkFRaVM5a1hjcjV3dU1m
|
||||||
|
WHNnSWhSN1l4ZVEwUkhXZVg3UFRZQStSVllFcEEKLT4gc3NoLWVkMjU1MTkgejFP
|
||||||
|
Y1p3IFUreGtraXo5aXM2OTFKcjZkL2p0ZEVwaEFXL3B5R2M1Q1J2elZYVityRUkK
|
||||||
|
bk80bnp1UzgzdmFqV0RJaVFhaytPWnJpQ0Y4Wmg1M2xLbGJyUzZzazlMUQotLS0g
|
||||||
|
dlZiRzZVSkYwbEVDaEVzZUhoRUkwMUpTM3pyOWJBaHUzZG8vejdmVklBYwpirejN
|
||||||
|
5cR1roLwVsunUkn+gnaMCYk+tDlaZABGXAC94k9RQVF06KquxeK0S17KOeQNn9Gb
|
||||||
|
N70JDklLLfuDsWbry6rIDYqsiEmTKi0WXhn44E1PaXQ=
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
@@ -21,6 +21,23 @@ in
|
|||||||
};
|
};
|
||||||
services = {
|
services = {
|
||||||
actualbudget.enable = lib.mkDefault true;
|
actualbudget.enable = lib.mkDefault true;
|
||||||
|
actualtap = {
|
||||||
|
enable = lib.mkDefault true;
|
||||||
|
instances = {
|
||||||
|
budget1 = {
|
||||||
|
port = 3031;
|
||||||
|
path = "/actualtap1";
|
||||||
|
budgetIdFile = ../presets/services/actualtap/budget1-id.age;
|
||||||
|
apiKeyFile = ../presets/services/actualtap/budget1-api-key.age;
|
||||||
|
};
|
||||||
|
budget2 = {
|
||||||
|
port = 3032;
|
||||||
|
path = "/actualtap2";
|
||||||
|
budgetIdFile = ../presets/services/actualtap/budget2-id.age;
|
||||||
|
apiKeyFile = ../presets/services/actualtap/budget2-api-key.age;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
caddy.enable = lib.mkDefault true;
|
caddy.enable = lib.mkDefault true;
|
||||||
cloudflare.enable = lib.mkDefault true;
|
cloudflare.enable = lib.mkDefault true;
|
||||||
cloudflared.enable = lib.mkDefault true;
|
cloudflared.enable = lib.mkDefault true;
|
||||||
|
|||||||
Reference in New Issue
Block a user