Compare commits

...

5 commits

26 changed files with 265 additions and 132 deletions

View file

@ -49,4 +49,5 @@
ln -f -s ${../../keys/PatC.key} /run/decrypt.key.pub
'';
boot.binfmt.emulatedSystems = ["aarch64-linux" "riscv64-linux"];
nix.settings.system-features = ["kvm" "nixos-test"];
}

View file

@ -26,7 +26,9 @@
./guests.nix
];
services.xserver = {
layout = "de";
xkbVariant = "bone";
xkb = {
layout = "de";
variant = "bone";
};
};
}

View file

@ -15,9 +15,9 @@
paperlessdomain = "ppl.${config.secrets.secrets.global.domains.web}";
ttrssdomain = "rss.${config.secrets.secrets.global.domains.web}";
vaultwardendomain = "pw.${config.secrets.secrets.global.domains.web}";
spotifydomain = "spotify.${config.secrets.secrets.global.domains.web}";
apispotifydomain = "api.spotify.${config.secrets.secrets.global.domains.web}";
autheliadomain = "auth.${config.secrets.secrets.global.domains.web}";
spotifydomain = "sptfy.${config.secrets.secrets.global.domains.web}";
apispotifydomain = "apisptfy.${config.secrets.secrets.global.domains.web}";
kanidmdomain = "auth.${config.secrets.secrets.global.domains.web}";
ipOf = hostName: lib.net.cidr.host config.secrets.secrets.global.net.ips."${config.guests.${hostName}.nodeName}" config.secrets.secrets.global.net.privateSubnetv4;
in {
services.nginx = {
@ -182,7 +182,7 @@ in {
'';
};
upstreams.apispotify = {
servers."${ipOf "yourspotify"}:8080" = {};
servers."${ipOf "yourspotify"}:3000" = {};
extraConfig = ''
zone spotify 64k ;
@ -214,20 +214,20 @@ in {
'';
};
upstreams.authelia = {
servers."${ipOf "authelia"}:${toString nodes.elisabeth-authelia.config.services.authelia.instances.main.settings.server.port}" = {};
upstreams.kanidm = {
servers."${ipOf "kanidm"}:3000" = {};
extraConfig = ''
zone authelia 64k ;
zone kanidm 64k ;
keepalive 5 ;
'';
};
virtualHosts.${autheliadomain} = {
virtualHosts.${kanidmdomain} = {
forceSSL = true;
useACMEHost = "web";
locations."/".proxyPass = "http://authelia";
locations."/".proxyPass = "https://kanidm";
extraConfig = ''
client_max_body_size 4G ;
proxy_ssl_verify off ;
'';
};
};
@ -268,7 +268,7 @@ in {
../../modules/config
../../modules/services/${guestName}.nix
{
node.secretsDir = ./secrets/${guestName};
node.secretsDir = config.node.secretsDir + "/${guestName}";
systemd.network.networks."10-${config.guests.${guestName}.networking.mainLinkName}" = {
DHCP = lib.mkForce "no";
address = [
@ -319,7 +319,7 @@ in {
// mkContainer "ollama" {}
// mkContainer "ttrss" {}
// mkContainer "yourspotify" {}
// mkContainer "authelia" {}
// mkContainer "kanidm" {}
// mkContainer "nextcloud" {
enablePanzer = true;
}

Binary file not shown.

View file

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIITsf7dXoAEyYeT2c95jRKKyUdMAT5dAovGVnbFOtyH3

Binary file not shown.

View file

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDfJQBQg5BlE03TZw3MLGGPK/YjYqR59OpYOEsvJX3u3

Binary file not shown.

View file

@ -0,0 +1,16 @@
age-encryption.org/v1
-> X25519 NZi/SK85OEWu7w/yvCOn3/l+obNYPsoTZJfBwSSL8gI
7dJPCeMxo1TKGrTH0wWxMB6Y46sph5xGv4JzNeTDtfI
-> piv-p256 XTQkUA AkuxoMo1sCU9PHemSyv5b0xBIK+n5x6OI1Q/VmflaK/o
71KGxc8CXfBhbIBp5NqItWDRvTAyrsJMFSz+O5xRms4
-> piv-p256 ZFgiIw AtA2xJwEhw2jX85m/9JsNyOHdmv2u7tfAMvQdfKkZ6N+
7MbtW54kju2yaIKwn2enFlO6t6othyMP05GPurOB7YM
-> piv-p256 5vmPtQ Ah/kiptBGGyYTGSpjvXoFW7yV33gNE7DuXzSIcupOm1I
cVhABpZEkaPkXEbtk4PPq4z0BTH9kazY2n6jFlaa9YQ
-> piv-p256 ZFgiIw A3GbyGhthzf+oAeMKiI/39MiHvEykf7EkiiW81000Wq5
vMTauia+psU/AtxhriecJci6uONm8BR3db1qPbTANzk
-> *-grease
6agZ0e3ziYasFWtZqR76cVifklgY8kmv531Z79Fr
--- j9TlSPpi3L50WqQw3YD8P0zI0cboA18D6LqzJ1TAYKQ
¿áؘß5©<35>[—b-_C¶BX®J†¾t\BêÙE¦ö¥õ)ŸmŒù´É;¼º{Ž¨º†2a÷Ã
êÖúÚ$é½Ç

View file

@ -30,6 +30,7 @@
freshrss = uidGid 220;
mongodb = uidGid 221;
authelia-main = uidGid 222;
kanidm = uidGid 223;
paperless = uidGid 315;
systemd-oom = uidGid 300;
systemd-coredump = uidGid 301;

View file

@ -74,6 +74,13 @@ in {
email = "patrick@${config.secrets.secrets.global.domains.mail_public}";
groups = ["admin" "forgejo_admin"];
};
users.test = {
disabled = false;
displayname = "Test";
password = "$argon2id$v=19$m=4096,t=3,p=1$cmJuaWJldGRheA$kG4NCJRryXTCe/8Jc2/BBnEmlWSRwq4pZG7LH7fKs/o";
email = "test@${config.secrets.secrets.global.domains.mail_public}";
groups = [];
};
});
};
};

View file

@ -1,6 +1,6 @@
{config, ...}: {
age.secrets.cloudflare_token_dns = {
rekeyFile = "${config.node.secretsDir}/cloudflare_api_token.age";
rekeyFile = config.node.secretsDir + "/cloudflare_api_token.age";
mode = "440";
};
# So we only update the A record

View file

@ -84,12 +84,11 @@ in {
SEND_AS_PLAIN_TEXT = true;
};
oauth2_client = {
ACCOUNT_LINKING = "auto";
USERNAME = "userid";
ACCOUNT_LINKING = "login";
ENABLE_AUTO_REGISTRATION = true;
OPENID_CONNECT_SCOPES = "email profile";
REGISTER_EMAIL_CONFIRM = false;
UPDATE_AVATAR = true;
USERNAME = "email";
};
# packages.ENABLED = true;
repository = {
@ -109,8 +108,9 @@ in {
# port forwarding in elisabeth
};
service = {
DISABLE_REGISTRATION = false;
SHOW_REGISTRATION_BUTTON = false;
DISABLE_REGISTRATION = true;
ALLOW_ONLY_EXTERNAL_REGISTRATION = true;
SHOW_REGISTRATION_BUTTON = true;
REGISTER_EMAIL_CONFIRM = false;
ENABLE_NOTIFY_MAIL = true;
DEFAULT_KEEP_EMAIL_PRIVATE = true;
@ -142,9 +142,15 @@ in {
"--key"
clientId
"--auto-discover-url"
"https://auth.${config.secrets.secrets.global.domains.web}/.well-known/openid-configuration"
"https://auth.${config.secrets.secrets.global.domains.web}/oauth2/openid/${clientId}/.well-known/openid-configuration"
"--required-claim-name"
"groups"
"--scopes"
"email"
"--scopes"
"profile"
"--scopes"
"groups"
"--group-claim-name"
"groups"
"--admin-group"

View file

@ -0,0 +1,42 @@
{config, ...}: let
kanidmdomain = "auth.${config.secrets.secrets.global.domains.web}";
in {
networking.firewall.allowedTCPPorts = [3000];
environment.persistence."/persist".directories = [
{
directory = "/var/lib/kanidm";
user = "kanidm";
group = "kanidm";
mode = "0700";
}
];
age.secrets = {
kanidm-cert = {
rekeyFile = config.node.secretsDir + "/cert.age";
group = "kanidm";
mode = "440";
};
kanidm-key = {
rekeyFile = config.node.secretsDir + "/key.age";
group = "kanidm";
mode = "440";
};
};
services.kanidm = {
enableServer = true;
serverSettings = {
domain = kanidmdomain;
origin = "https://${kanidmdomain}";
tls_chain = config.age.secrets.kanidm-cert.path;
tls_key = config.age.secrets.kanidm-key.path;
bindaddress = "0.0.0.0:3000";
trust_x_forward_for = true;
};
enableClient = true;
clientSettings = {
uri = config.services.kanidm.serverSettings.origin;
verify_ca = true;
verify_hostnames = true;
};
};
}

View file

@ -15,7 +15,6 @@
mkIf
mkOption
mkPackageOption
optional
optionalAttrs
types
;
@ -23,7 +22,7 @@
configEnv = concatMapAttrs (name: value:
optionalAttrs (value != null) {
name =
${name} =
if isBool value
then boolToString value
else toString value;
@ -33,12 +32,20 @@
configFile = pkgs.writeText "your_spotify.env" (concatStrings (mapAttrsToList (name: value: "${name}=${value}\n") configEnv));
in {
options.services.your_spotify = let
inherit (types) nullOr port str bool package;
inherit (types) nullOr port str path bool package;
in {
enable = mkEnableOption "your_spotify";
enableLocalDB = mkEnableOption "a local mongodb instance";
enableNginxVirtualHost = mkEnableOption "a ngnix virtual Host for your client";
nginxVirtualHost = mkOption {
type = nullOr str;
default = null;
description = ''
If set creates an nginx virtual host for the client.
In most cases this should be the CLIENT_ENDPOINT without
protocol prefix.
'';
};
package = mkPackageOption pkgs "your_spotify" {};
@ -47,6 +54,23 @@ in {
default = cfg.package.client.override {apiEndpoint = cfg.settings.API_ENDPOINT;};
description = "Client package to use.";
};
spotifyPublicFile = mkOption {
type = path;
description = ''
The public key of your Spotify application
[Creating the Spotify Application](https://github.com/Yooooomi/your_spotify#creating-the-spotify-application)
'';
};
spotifySecretFile = mkOption {
type = path;
description = ''
The secret key of your Spotify application
[Creating the Spotify Application](https://github.com/Yooooomi/your_spotify#creating-the-spotify-application)
Note that you may want to set this using the `environmentFile` config option to prevent
your secret from being world-readable in the nix store.
'';
};
settings = mkOption {
type = types.submodule {
@ -54,7 +78,10 @@ in {
options = {
CLIENT_ENDPOINT = mkOption {
type = str;
description = "The endpoint of your web application";
description = ''
The endpoint of your web application
Has to include a protocol Prefix (e.g. `http://`)
'';
example = "https://your_spotify.example.org";
};
API_ENDPOINT = mkOption {
@ -64,35 +91,18 @@ in {
This api has to be reachable from the device you use the website from not from the server.
This means that for example you may need two nginx virtual hosts if you want to expose this on the
internet.
Has to include a protocol Prefix (e.g. `http://`)
'';
default = "http://localhost:8080";
default = "https://localhost:3000";
};
spotifyPublic = mkOption {
type = nullOr str;
description = ''
The public key of your Spotify application
[Creating the Spotify Application](https://github.com/Yooooomi/your_spotify#creating-the-spotify-application)
'';
default = null;
};
spotifySecret = mkOption {
type = nullOr str;
description = ''
The secret key of your Spotify application
[Creating the Spotify Application](https://github.com/Yooooomi/your_spotify#creating-the-spotify-application)
Note that you may want to set this using the `environmentFile` config option to prevent
your secret from being world-readable in the nix store.
'';
default = null;
};
cors = mkOption {
CORS = mkOption {
type = nullOr str;
description = ''
List of comma-separated origin allowed, or nothing to allow any origin
'';
default = null;
};
maxImportCacheSize = mkOption {
MAX_IMPORT_CACHESIZE = mkOption {
type = str;
description = ''
The maximum element in the cache when importing data from an outside source,
@ -100,40 +110,40 @@ in {
'';
default = "Infinite";
};
mongoEndpoint = mkOption {
MONGO_ENDPOINT = mkOption {
type = str;
description = ''
The endpoint of the Mongo database.
'';
default = "mongodb://localhost:27017/your_spotify";
};
port = mkOption {
PORT = mkOption {
type = port;
description = "The port of the api server";
default = 8080;
default = 3000;
};
timezone = mkOption {
TIMEZONE = mkOption {
type = str;
description = ''
The timezone of your stats, only affects read requests since data is saved with UTC time
'';
default = "Europe/Paris";
};
logLevel = mkOption {
LOG_LEVEL = mkOption {
type = str;
description = ''
The log level, debug is useful if you encouter any bugs
'';
default = "info";
};
cookieValidityMs = mkOption {
COOKIE_VALIDITY_MS = mkOption {
type = str;
description = ''
Validity time of the authentication cookie
'';
default = "1h";
};
mongoNoAdminRights = mkOption {
MONGO_NO_ADMIN_RIGHTS = mkOption {
type = bool;
description = ''
Do not ask for admin right on the Mongo database
@ -143,33 +153,22 @@ in {
};
};
};
environmentFile = mkOption {
type = with types; nullOr path;
default = null;
example = "/var/lib/your_spotify.env";
description = ''
Additional environment file as defined in {manpage}`systemd.exec(5)`.
Secrets like {env}`SPOTIFY_SECRET`
may be passed to the service without adding them to the world-readable Nix store.
Note that this file needs to be available on the host on which
`your_spotify` is running.
'';
};
};
config = mkIf cfg.enable {
systemd.services.your_spotify = {
after = ["network.target"];
script = ''
export SPOTIFY_PUBLIC=$(< "$CREDENTIALS_DIRECTORY/SPOTIFY_PUBLIC")
export SPOTIFY_SECRET=$(< "$CREDENTIALS_DIRECTORY/SPOTIFY_SECRET")
${pkgs.your_spotify}/bin/your_spotify_migrate
exec ${pkgs.your_spotify}/bin/your_spotify_server
'';
serviceConfig = {
User = "your_spotify";
Group = "your_spotify";
DynamicUser = true;
EnvironmentFile = [configFile] ++ optional (cfg.environmentFile != null) cfg.environmentFile;
ExecStartPre = "${pkgs.your_spotify}/bin/your_spotify_migrate";
ExecStart = "${pkgs.your_spotify}/bin/your_spotify_server";
EnvironmentFile = [configFile];
StateDirectory = "your_spotify";
LimitNOFILE = "1048576";
PrivateTmp = true;
@ -177,12 +176,12 @@ in {
StateDirectoryMode = "0700";
Restart = "always";
LoadCredential = ["SPOTIFY_PUBLIC:${cfg.spotifyPublicFile}" "SPOTIFY_SECRET:${cfg.spotifySecretFile}"];
# Hardening
CapabilityBoundingSet = "";
LockPersonality = true;
MemoryDenyWriteExecute = true;
DevicePolicy = "closed";
SupplementaryGroups = ["dialout"];
#MemoryDenyWriteExecute = true;
#NoNewPrivileges = true; # Implied by DynamicUser
PrivateUsers = true;
#PrivateTmp = true; # Implied by DynamicUser
@ -201,7 +200,6 @@ in {
"AF_INET"
"AF_INET6"
"AF_NETLINK"
"AF_UNIX"
];
RestrictNamespaces = true;
RestrictRealtime = true;
@ -209,17 +207,18 @@ in {
SystemCallArchitectures = "native";
SystemCallFilter = [
"@system-service"
"@mount" # Required by platformio for chroot
"@pkey"
];
UMask = "0077";
};
wantedBy = ["multi-user.target"];
};
services.nginx = mkIf cfg.enableNginxVirtualHost {
services.nginx = mkIf (cfg.nginxVirtualHost != null) {
enable = true;
virtualHosts.${cfg.settings.CLIENT_ENDPOINT} = {
virtualHosts.${cfg.nginxVirtualHost} = {
root = cfg.clientPackage;
locations."/".extraConfig = ''
try_files = "$uri $uri/ /index.html;
try_files = $uri $uri/ /index.html ;
'';
};
};
@ -228,6 +227,3 @@ in {
};
};
}
# nginx gaten
# systemd hardening(e.g. esphome)

View file

@ -1,19 +1,31 @@
{config, ...}: {
{
config,
pkgs,
...
}: {
networking.firewall.allowedTCPPorts = [3000 80];
imports = [./your_spotify_m.nix];
age.secrets.spotify = {
owner = "your_spotify";
age.secrets.spotifySecret = {
owner = "root";
mode = "440";
rekeyFile = ../../secrets/your_spotify.age;
rekeyFile = config.node.secretsDir + "/spotifySecret.age";
};
age.secrets.spotifyPublic = {
owner = "root";
mode = "440";
rekeyFile = config.node.secretsDir + "/spotifyPublic.age";
};
services.your_spotify = {
#enable = true;
enable = true;
spotifySecretFile = config.age.secrets.spotifySecret.path;
spotifyPublicFile = config.age.secrets.spotifyPublic.path;
settings = {
CLIENT_ENDPOINT = "https://spotify.${config.secrets.secrets.global.domains.web}";
API_ENDPOINT = "https://api.spotify.${config.secrets.secrets.global.domains.web}";
CLIENT_ENDPOINT = "https://sptfy.${config.secrets.secrets.global.domains.web}";
API_ENDPOINT = "https://apisptfy.${config.secrets.secrets.global.domains.web}";
MONGO_NO_ADMIN_RIGHTS = false;
};
enableLocalDB = true;
enableNginxVirtualHost = true;
environmentFile = config.age.secrets.spotify.path;
nginxVirtualHost = "sptfy.${config.secrets.secrets.global.domains.web}";
};
environment.persistence."/persist".directories = [
{
@ -21,4 +33,5 @@
directory = config.services.mongodb.dbpath;
}
];
services.mongodb.package = pkgs.mongodb-bin;
}

View file

@ -32,7 +32,7 @@ inputs: let
nixpkgs.overlays = pkgs.overlays;
nixpkgs.config = pkgs.config;
node.name = name;
node.secretsDir = ../hosts/${name}/secrets;
node.secretsDir = ../. + "/hosts/${name}/secrets";
}
../hosts/${name}
];

View file

@ -6,6 +6,7 @@
your_spotify = super.callPackage ./your_spotify.nix {};
deploy = super.callPackage ./deploy.nix {};
minify = super.callPackage ./minify {};
mongodb-bin = super.callPackage ./mongodb-bin.nix {};
awakened-poe-trade = super.callPackage ./awakened-poe-trade.nix {};
neovim-clean = super.neovim-unwrapped.overrideAttrs (_neovimFinal: neovimPrev: {
nativeBuildInputs = (neovimPrev.nativeBuildInputs or []) ++ [super.makeWrapper];

37
pkgs/mongodb-bin.nix Normal file
View file

@ -0,0 +1,37 @@
{
stdenv,
fetchurl,
openssl,
xz,
curl,
autoPatchelfHook,
libgcc,
}:
stdenv.mkDerivation {
pname = "mongodb-bin";
version = "1.0.0";
srcs = [
(
fetchurl {
url = "https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu2204-6.0.14.tgz";
hash = "sha256-1MW3pVIffdxq63gY64ozM1erWM2ou2L8T+MTfG+ZPLg=";
}
)
(
fetchurl {
url = "https://downloads.mongodb.com/compass/mongosh-2.1.5-linux-x64.tgz";
hash = "sha256-R1GGB0ZGqmpJtMUNF2+EJK6iNiChHuoHyOf2vKDcOKA=";
}
)
];
sourceRoot = ".";
nativeBuildInputs = [
autoPatchelfHook
];
buildPhase = ''
mkdir -p $out/bin
cp mongosh-2.1.5-linux-x64/bin/mongosh $out/bin/mongo
cp mongodb-linux-x86_64-ubuntu2204-6.0.14/bin/mongod $out/bin/mongod
'';
buildInputs = [openssl curl xz libgcc];
}

View file

@ -4,46 +4,58 @@
fetchYarnDeps,
makeWrapper,
nodejs,
yarn,
prefetch-yarn-deps,
lib,
callPackage,
}: let
version = "1.7.3";
src_o = fetchFromGitHub {
version = "1.8.0";
src = fetchFromGitHub {
owner = "Yooooomi";
repo = "your_spotify";
rev = "refs/tags/${version}";
hash = "sha256-/0xKktywwGcqsuwLytWBJ3O6ADHg1nP6BdMRlkW5ErY=";
hash = "sha256-umm7J5ADY2fl+tjs6Qeda5MX2P55u0eCqwW+DWLK8Kc=";
};
client = callPackage ./your_spotify_client.nix {inherit src_o version;};
client = callPackage ./your_spotify_client.nix {inherit src version;};
in
mkYarnPackage rec {
inherit version;
inherit version src;
pname = "your_spotify";
src = "${src_o}/server";
offlineCache = fetchYarnDeps {
yarnLock = src + "/yarn.lock";
hash = "sha256-3ZK+p3RoHHjPu53MLGSho7lEroZ77vUrZ2CjDwIUQTs=";
hash = "sha256-pj6owoEPx9gdtFvXF8E89A+Thhe/7m0+OJU6Ttc6ooA=";
};
postPatch = ''
substituteInPlace tsconfig.json --replace-quiet '"extends": "../tsconfig.json",' ""
configurePhase = ''
runHook preConfigure
export HOME=$(mktemp -d)
yarn config --offline set yarn-offline-mirror $offlineCache
fixup-yarn-lock yarn.lock
yarn install --offline --frozen-lockfile --ignore-platform --ignore-scripts --no-progress --non-interactive
patchShebangs node_modules/
runHook postConfigure
'';
buildPhase = ''
runHook preBuild
pushd ./deps/server
ls -lah
pushd ./apps/server/
yarn --offline run build
popd
runHook postBuild
'';
nativeBuildInputs = [makeWrapper];
nativeBuildInputs = [makeWrapper yarn prefetch-yarn-deps];
installPhase = ''
mkdir -p $out
cp -r $node_modules $out/node_modules
cp -r ./deps/server/{lib,package.json} $out
cp -r node_modules $out/node_modules
cp -r ./apps/server/{lib,package.json} $out
mkdir -p $out/bin
makeWrapper ${lib.escapeShellArg (lib.getExe nodejs)} "$out/bin/your_spotify_migrate" \
--add-flags "$out/lib/migrations.js"
makeWrapper ${lib.escapeShellArg (lib.getExe nodejs)} "$out/bin/your_spotify_server" \
--add-flags "$out/lib/bin/www.js"
--add-flags "$out/lib/index.js"
'';
doDist = false;
passthru = {

View file

@ -3,31 +3,42 @@
makeWrapper,
fetchYarnDeps,
apiEndpoint ? "localhost:8080",
src_o,
src,
version,
yarn,
prefetch-yarn-deps,
}:
mkYarnPackage rec {
inherit version;
inherit version src;
pname = "your_spotify_client";
src = "${src_o}/client";
offlineCache = fetchYarnDeps {
yarnLock = src + "/yarn.lock";
hash = "sha256-9UfRVv7M9311lesnr19oThYnzB9cK23XNZejJY/Fd24=";
hash = "sha256-pj6owoEPx9gdtFvXF8E89A+Thhe/7m0+OJU6Ttc6ooA=";
};
postPatch = ''
substituteInPlace tsconfig.json --replace-quiet '"extends": "../tsconfig.json",' ""
configurePhase = ''
runHook preConfigure
export HOME=$(mktemp -d)
yarn config --offline set yarn-offline-mirror $offlineCache
fixup-yarn-lock yarn.lock
yarn install --offline --frozen-lockfile --ignore-platform --ignore-scripts --no-progress --non-interactive
patchShebangs node_modules/
runHook postConfigure
'';
buildPhase = ''
runHook preBuild
pushd ./deps/client_ts
pushd ./apps/client/
pwd
yarn --offline run build
popd
runHook postBuild
'';
nativeBuildInputs = [makeWrapper];
nativeBuildInputs = [makeWrapper yarn prefetch-yarn-deps];
installPhase = ''
mkdir -p $out
cp -r ./deps/client_ts/build/* $out
cp -r ./apps/client/build/* $out
substituteInPlace $out/variables-template.js --replace-quiet '__API_ENDPOINT__' "${apiEndpoint}"
mv $out/variables-template.js $out/variables.js
'';

Binary file not shown.

View file

@ -1,15 +0,0 @@
age-encryption.org/v1
-> X25519 ggSXy/sQbB5RIx9y+7b9gx+Osn4CDC1llDZpEurSUlQ
eaRyyBSWaPjuY0VQOIKef+jeJrKP/bjn0A3ptY1Yi1c
-> piv-p256 XTQkUA A712bv8pNfgCw6BY8uko50ZT6ctKw0aKGMzw21ntFoH9
Od/YRbbeDhrsjrydRLpbJ29fb7FVVLNdHrqHIqADD90
-> piv-p256 ZFgiIw A7KV41jrxMfKZvJVInfcLH0SX22uRKrGx3Ce1RBK1ba0
o6DUQEhob61zHAj6o4l0wPLudMjsg8w2qyanKWn7ZsQ
-> piv-p256 5vmPtQ AjgfvHuq6ZktpH4hS5aMnT8OJnFLN0D0+ELXNvuaNyi/
ALCCRjJYI6CExt9Di4/p5Gcok5IO/nmuFV5wN7ZJYx0
-> piv-p256 ZFgiIw Amn+6yW9k49wRmdkooDqE185U/oZq69mcP2NbOq4l5Ty
aQbjyUaiBbf34Fg6HXxgcuVy5s69j4nhmZKelxlGx2Y
-> Zb-grease Kj7
L0fTYguif9Le7qsrbF1YsD43CgE
--- lGupwRLVGo0u7OcziXOmEFo6kA7NsvnMuCLWiIRdqA0
#yä^¢uŽf1ʶ¦®í6D²ëAôVIÕnhzÅG&ÄÀeGVðýºg&Mìq‰¬TííÉÜÉ]ð<>95ÑÕë/3µ9–ÐÑýõ<C3BD>.ßè=ŒÎôŸw~4»Û§Ãw~H3\c>ù؆Κš¯ñZÙ

View file

@ -13,6 +13,7 @@
chromium
python3
jq
osu-lazer-bin
];
};
}

View file

@ -53,7 +53,7 @@
};
"13" = {
icon = config.images.images."player.png";
switch_page = 1;
switch_page = 2;
};
};
"1" = {