Compare commits

..

12 commits

24 changed files with 229 additions and 447 deletions

View file

@ -232,18 +232,18 @@
"nixpkgs": "nixpkgs_7" "nixpkgs": "nixpkgs_7"
}, },
"locked": { "locked": {
"lastModified": 1731494335, "lastModified": 1728598146,
"narHash": "sha256-G1G2WRGgIOFNmlJglfqEupSg0VWHgODbBJzp5xo+cYY=", "narHash": "sha256-8zAvVSR3chBSJ7YKW+MYC1mrDxtZDFBPVobfO4KPXzg=",
"ref": "dtth-fork", "ref": "dtth-fork",
"rev": "c414bb78f27b20df4463c36a5851c94cfe9c79b0", "rev": "fc6bd96aef92d7796d9c7663ac23e3fa837f8ddb",
"revCount": 3367, "revCount": 3218,
"type": "git", "type": "git",
"url": "ssh://gitea@git.dtth.ch/nki-dtth/phanpy" "url": "ssh://gitea@git.dtth.ch/nki/phanpy"
}, },
"original": { "original": {
"ref": "dtth-fork", "ref": "dtth-fork",
"type": "git", "type": "git",
"url": "ssh://gitea@git.dtth.ch/nki-dtth/phanpy" "url": "ssh://gitea@git.dtth.ch/nki/phanpy"
} }
}, },
"fenix": { "fenix": {
@ -742,11 +742,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1731887066, "lastModified": 1728337164,
"narHash": "sha256-uw7K/RsYioJicV79Nl39yjtfhdfTDU2aRxnBgvFhkZ8=", "narHash": "sha256-VdRTjJFyq4Q9U7Z/UoC2Q5jK8vSo6E86lHc2OanXtvc=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "f3a2ff69586f3a54b461526e5702b1a2f81e740a", "rev": "038630363e7de57c36c417fd2f5d7c14773403e4",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -817,15 +817,15 @@
"lix": { "lix": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1729298361, "lastModified": 1723503926,
"narHash": "sha256-hiGtfzxFkDc9TSYsb96Whg0vnqBVV7CUxyscZNhed0U=", "narHash": "sha256-Rosl9iA9MybF5Bud4BTAQ9adbY81aGmPfV8dDBGl34s=",
"rev": "ad9d06f7838a25beec425ff406fe68721fef73be", "rev": "bcaeb6388b8916ac6d1736e3aa2b13313e6a6bd2",
"type": "tarball", "type": "tarball",
"url": "https://git.lix.systems/api/v1/repos/lix-project/lix/archive/ad9d06f7838a25beec425ff406fe68721fef73be.tar.gz?rev=ad9d06f7838a25beec425ff406fe68721fef73be" "url": "https://git.lix.systems/api/v1/repos/lix-project/lix/archive/bcaeb6388b8916ac6d1736e3aa2b13313e6a6bd2.tar.gz"
}, },
"original": { "original": {
"type": "tarball", "type": "tarball",
"url": "https://git.lix.systems/lix-project/lix/archive/2.91.1.tar.gz" "url": "https://git.lix.systems/lix-project/lix/archive/2.91.0.tar.gz"
} }
}, },
"lix-module": { "lix-module": {
@ -838,15 +838,15 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1729360442, "lastModified": 1723510904,
"narHash": "sha256-6U0CyPycIBc04hbYy2hBINnVso58n/ZyywY2BD3hu+s=", "narHash": "sha256-zNW/rqNJwhq2lYmQf19wJerRuNimjhxHKmzrWWFJYts=",
"rev": "9098ac95768f7006d7e070b88bae76939f6034e6", "rev": "622a2253a071a1fb97a4d3c8103a91114acc1140",
"type": "tarball", "type": "tarball",
"url": "https://git.lix.systems/api/v1/repos/lix-project/nixos-module/archive/9098ac95768f7006d7e070b88bae76939f6034e6.tar.gz?rev=9098ac95768f7006d7e070b88bae76939f6034e6" "url": "https://git.lix.systems/api/v1/repos/lix-project/nixos-module/archive/622a2253a071a1fb97a4d3c8103a91114acc1140.tar.gz"
}, },
"original": { "original": {
"type": "tarball", "type": "tarball",
"url": "https://git.lix.systems/lix-project/nixos-module/archive/2.91.1-1.tar.gz" "url": "https://git.lix.systems/lix-project/nixos-module/archive/2.91.0.tar.gz"
} }
}, },
"mpd-mpris": { "mpd-mpris": {
@ -1022,11 +1022,11 @@
}, },
"nixpkgs-unstable": { "nixpkgs-unstable": {
"locked": { "locked": {
"lastModified": 1731890469, "lastModified": 1728409405,
"narHash": "sha256-D1FNZ70NmQEwNxpSSdTXCSklBH1z2isPR84J6DQrJGs=", "narHash": "sha256-kk530XBUGDpt0DQbyUb3yDpSddPqF9PA5KTo/nsmmg0=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "5083ec887760adfe12af64830a66807423a859a7", "rev": "1366d1af8f58325602280e43ed6233849fb92216",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -1166,11 +1166,11 @@
}, },
"nixpkgs_9": { "nixpkgs_9": {
"locked": { "locked": {
"lastModified": 1731239293, "lastModified": 1726838390,
"narHash": "sha256-q2yjIWFFcTzp5REWQUOU9L6kHdCDmFDpqeix86SOvDc=", "narHash": "sha256-NmcVhGElxDbmEWzgXsyAjlRhUus/nEqPC5So7BOJLUM=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "9256f7c71a195ebe7a218043d9f93390d49e6884", "rev": "944b2aea7f0a2d7c79f72468106bc5510cbf5101",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -1549,11 +1549,11 @@
"rust-overlay": "rust-overlay_4" "rust-overlay": "rust-overlay_4"
}, },
"locked": { "locked": {
"lastModified": 1731934405, "lastModified": 1728746553,
"narHash": "sha256-5lRtAsJjjc9BkTbpuhjgMgDpXKYkYcGDydh+xJzDVyU=", "narHash": "sha256-BlZpmTt6wyMIpJvd5nEWGgqJQbtjVTzBlYYQVShZ7Io=",
"owner": "natsukagami", "owner": "natsukagami",
"repo": "youmubot", "repo": "youmubot",
"rev": "a4fab5438bebd9c399f628151958789c7f2454a6", "rev": "c5354e30ad40f67938deed1deb5ea92bb168a586",
"type": "github" "type": "github"
}, },
"original": { "original": {

View file

@ -31,7 +31,7 @@
}; };
arion.url = github:hercules-ci/arion; arion.url = github:hercules-ci/arion;
lix-module = { lix-module = {
url = "https://git.lix.systems/lix-project/nixos-module/archive/2.91.1-1.tar.gz"; url = "https://git.lix.systems/lix-project/nixos-module/archive/2.91.0.tar.gz";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
@ -46,7 +46,7 @@
url = github:natsukagami/mpd-mpris; url = github:natsukagami/mpd-mpris;
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
dtth-phanpy.url = "git+ssh://gitea@git.dtth.ch/nki-dtth/phanpy?ref=dtth-fork"; dtth-phanpy.url = "git+ssh://gitea@git.dtth.ch/nki/phanpy?ref=dtth-fork";
conduit.url = "gitlab:famedly/conduit/v0.9.0"; conduit.url = "gitlab:famedly/conduit/v0.9.0";
nix-gaming.url = github:fufexan/nix-gaming; nix-gaming.url = github:fufexan/nix-gaming;

View file

@ -39,7 +39,7 @@ in
systemd.user.startServices = "sd-switch"; systemd.user.startServices = "sd-switch";
# Audio stuff! # Audio stuff!
# services.easyeffects.enable = true; services.easyeffects.enable = true;
# Bluetooth controls # Bluetooth controls
# services.mpris-proxy.enable = true; # services.mpris-proxy.enable = true;

View file

@ -14,9 +14,8 @@
# Let Home Manager install and manage itself. # Let Home Manager install and manage itself.
programs.home-manager.enable = true; programs.home-manager.enable = true;
# Temporarily disable the manuals # Enable the manual so we don't have to load it
manual.html.enable = false; manual.html.enable = true;
# manual.manpage.enable = false;
# Packages that are not in programs section # Packages that are not in programs section
home.packages = with pkgs; [ home.packages = with pkgs; [

View file

@ -37,12 +37,7 @@
# Enable X11 configuration # Enable X11 configuration
linux.graphical.type = "wayland"; linux.graphical.type = "wayland";
linux.graphical.wallpaper = ./images/pixiv_18776904.png; linux.graphical.wallpaper = ./images/pixiv_18776904.png;
linux.graphical.startup = with pkgs; [ linux.graphical.defaults.webBrowser = "librewolf.desktop";
zen-browser-bin
thunderbird
vesktop
];
linux.graphical.defaults.webBrowser = "zen.desktop";
programs.my-sway.enable = true; programs.my-sway.enable = true;
programs.my-sway.fontSize = 15.0; programs.my-sway.fontSize = 15.0;
programs.my-sway.enableLaptopBars = false; programs.my-sway.enableLaptopBars = false;

View file

@ -38,6 +38,7 @@ in
librewolf librewolf
thunderbird thunderbird
vesktop vesktop
premid
]; ];
}; };
defaults.webBrowser = mkOption { defaults.webBrowser = mkOption {
@ -57,6 +58,7 @@ in
feh # For images? feh # For images?
deluge # Torrent client deluge # Torrent client
pavucontrol # PulseAudio control panel pavucontrol # PulseAudio control panel
thunderbird # Email
sublime-music # For navidrome sublime-music # For navidrome
# cinny-desktop # cinny-desktop
gajim gajim
@ -64,7 +66,7 @@ in
# Audio # Audio
qpwgraph # Pipewire graph qpwgraph # Pipewire graph
unstable.zotero zotero_7
libreoffice libreoffice
mpv # for anki mpv # for anki
@ -74,15 +76,15 @@ in
tdesktop tdesktop
whatsapp-for-linux whatsapp-for-linux
slack slack
zoom-us
librewolf
## CLI stuff ## CLI stuff
dex # .desktop file management, startup dex # .desktop file management, startup
# sct # Display color temperature # sct # Display color temperature
xdg-utils # Open stuff xdg-utils # Open stuff
wifi-indicator wifi-indicator
] ++ cfg.startup); ]);
nki.programs.discord.enable = pkgs.stdenv.isx86_64; nki.programs.discord.enable = pkgs.stdenv.isx86_64;
nki.programs.discord.package = pkgs.vesktop; nki.programs.discord.package = pkgs.vesktop;

View file

@ -61,12 +61,6 @@ let
''; '';
xdg.dataFile."dbus-1/services/org.freedesktop.Notifications.service".source = "${pkgs.kdePackages.plasma-workspace}/share/dbus-1/services/org.kde.plasma.Notifications.service"; xdg.dataFile."dbus-1/services/org.freedesktop.Notifications.service".source = "${pkgs.kdePackages.plasma-workspace}/share/dbus-1/services/org.kde.plasma.Notifications.service";
}; };
rofi-rbw-script = pkgs.writeShellApplication {
name = "rofi-rbw-script";
runtimeInputs = with pkgs; [ rofi wtype rofi-rbw ];
text = "rofi-rbw";
};
in in
with lib; with lib;
{ {
@ -75,7 +69,6 @@ with lib;
# Additional packages # Additional packages
home.packages = with pkgs; [ home.packages = with pkgs; [
wl-clipboard # Clipboard management wl-clipboard # Clipboard management
rofi-rbw-script
# Mimic the clipboard stuff in MacOS # Mimic the clipboard stuff in MacOS
(pkgs.writeShellScriptBin "pbcopy" '' (pkgs.writeShellScriptBin "pbcopy" ''
@ -86,16 +79,6 @@ with lib;
'') '')
]; ];
programs.rofi = {
enable = true;
package = pkgs.rofi-wayland;
cycle = true;
font = "monospace";
terminal = "${lib.getExe config.programs.kitty.package}";
theme = "Paper";
plugins = with pkgs; [ rofi-bluetooth rofi-calc rofi-rbw rofi-power-menu ];
};
home.sessionVariables = { home.sessionVariables = {
ANKI_WAYLAND = "1"; ANKI_WAYLAND = "1";
}; };

View file

@ -45,6 +45,12 @@ let
${pkgs.grim}/bin/grim -g (${pkgs.slurp}/bin/slurp) - | ${pkgs.swappy}/bin/swappy -f - ${pkgs.grim}/bin/grim -g (${pkgs.slurp}/bin/slurp) - | ${pkgs.swappy}/bin/swappy -f -
''; '';
rofi-rbw-script = pkgs.writeShellApplication {
name = "rofi-rbw-script";
runtimeInputs = with pkgs; [ rofi wtype rofi-rbw ];
text = "rofi-rbw";
};
ignored-devices = [ "Surface_Headphones" ]; ignored-devices = [ "Surface_Headphones" ];
playerctl = "${pkgs.playerctl}/bin/playerctl --ignore-player=${strings.concatStringsSep "," ignored-devices}"; playerctl = "${pkgs.playerctl}/bin/playerctl --ignore-player=${strings.concatStringsSep "," ignored-devices}";
@ -217,7 +223,7 @@ in
# Launcher # Launcher
"${mod}+space" = "exec rofi -show drun"; "${mod}+space" = "exec rofi -show drun";
"${mod}+tab" = "exec ${./rofi-window.py}"; "${mod}+tab" = "exec ${./rofi-window.py}";
"${mod}+shift+p" = "exec rofi-rbw-script"; "${mod}+shift+p" = "exec ${lib.getExe rofi-rbw-script}";
} // { } // {
## Splits ## Splits
"${mod}+v" = "split v"; "${mod}+v" = "split v";
@ -291,8 +297,7 @@ in
# Assigning windows to workspaces # Assigning windows to workspaces
assigns = { assigns = {
"${builtins.elemAt workspaces 0}" = [ "${builtins.elemAt workspaces 0}" = [
{ app_id = "^firefox$"; } { class = "^firefox$"; }
{ app_id = "^librewolf$"; }
]; ];
"${builtins.elemAt workspaces 1}" = [ "${builtins.elemAt workspaces 1}" = [
{ class = "^((d|D)iscord|((A|a)rm(c|C)ord))$"; } { class = "^((d|D)iscord|((A|a)rm(c|C)ord))$"; }
@ -300,8 +305,6 @@ in
{ app_id = "VencordDesktop"; } { app_id = "VencordDesktop"; }
{ class = "vesktop"; } { class = "vesktop"; }
{ app_id = "vesktop"; } { app_id = "vesktop"; }
{ class = "Slack"; }
]; ];
${extraWorkspaces.mail} = [ ${extraWorkspaces.mail} = [
{ app_id = "thunderbird"; } { app_id = "thunderbird"; }
@ -778,9 +781,14 @@ in
# For waybar # For waybar
font-awesome font-awesome
]); ]);
config.programs.rofi = mkIf cfg.enable { config.programs.rofi = mkIf cfg.enable {
font = lib.mkForce "monospace ${toString cfg.fontSize}"; enable = true;
package = pkgs.rofi-wayland;
cycle = true;
font = "monospace ${toString cfg.fontSize}";
terminal = cfg.terminal;
theme = "Paper";
plugins = with pkgs; [ rofi-bluetooth rofi-calc rofi-rbw rofi-power-menu ];
}; };
} }

View file

@ -29,8 +29,7 @@
# Graphical set up # Graphical set up
linux.graphical.type = "wayland"; linux.graphical.type = "wayland";
linux.graphical.wallpaper = ./images/wallpaper_0.png; linux.graphical.wallpaper = ./images/wallpaper_0.png;
linux.graphical.startup = with pkgs; [ zen-browser-bin thunderbird vesktop slack ]; linux.graphical.defaults.webBrowser = "librewolf.desktop";
linux.graphical.defaults.webBrowser = "zen.desktop";
# Enable sway # Enable sway
programs.my-sway.enable = true; programs.my-sway.enable = true;
programs.my-sway.fontSize = 14.0; programs.my-sway.fontSize = 14.0;
@ -97,25 +96,14 @@
# Multiple screen setup # Multiple screen setup
services.kanshi = with config.common.monitors; { services.kanshi = with config.common.monitors; {
enable = true; enable = true;
settings = [ profiles.undocked.outputs = [{ criteria = "LVDS-1"; }];
{ profiles.work-both.outputs = [
profile.name = "undocked"; { criteria = "eDP-1"; position = "0,${toString (builtins.floor ((2160 / work.scale - 1200) + 1200 / 3))}"; status = "enable"; }
profile.outputs = [{ criteria = "LVDS-1"; }]; { criteria = work.name; position = "1920,0"; }
} ];
{ profiles.work-one.outputs = [
profile.name = "work-both"; { criteria = "eDP-1"; status = "disable"; }
profile.outputs = [ { criteria = config.common.monitors.work.name; }
{ criteria = "eDP-1"; position = "0,${toString (builtins.floor ((2160 / work.scale - 1200) + 1200 / 3))}"; status = "enable"; }
{ criteria = work.name; position = "1920,0"; }
];
}
{
profile.name = "work-one";
profile.outputs = [
{ criteria = "eDP-1"; status = "disable"; }
{ criteria = work.name; }
];
}
]; ];
}; };

View file

@ -5,10 +5,10 @@ let
osu-pkg = with pkgs; with lib; osu-pkg = with pkgs; with lib;
appimageTools.wrapType2 rec { appimageTools.wrapType2 rec {
pname = "osu-lazer-bin"; pname = "osu-lazer-bin";
version = "2024.1115.3"; version = "2024.906.2";
src = fetchurl { src = fetchurl {
url = "https://github.com/ppy/osu/releases/download/${version}/osu.AppImage"; url = "https://github.com/ppy/osu/releases/download/${version}/osu.AppImage";
sha256 = "sha256-kwZHy0FfOUFIWvyOj0ghlQz05U+Lnzl5TgC4T6bhm7o="; sha256 = "1ddnac72xk9zsi9pmxg72xd3piq6s5hgh7vzb09mh4r5mkfd22fd";
}; };
extraPkgs = pkgs: with pkgs; [ icu ]; extraPkgs = pkgs: with pkgs; [ icu ];

View file

@ -48,14 +48,7 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
systemd.services.arion-authentik = { systemd.services.arion-authentik.serviceConfig.EnvironmentFile = cfg.envFile;
serviceConfig.EnvironmentFile = cfg.envFile;
serviceConfig.Type = "notify";
serviceConfig.NotifyAccess = "all";
script = lib.mkBefore ''
${lib.getExe pkgs.wait4x} http http://127.0.0.1:${toString cfg.port} --expect-status-code 200 -t 0 -q -- systemd-notify --ready &
'';
};
virtualisation.arion.projects.authentik.settings = { virtualisation.arion.projects.authentik.settings = {
services.postgresql.service = { services.postgresql.service = {
image = images.postgresql; image = images.postgresql;

View file

@ -33,7 +33,7 @@ with lib; {
{ {
systemd.services.heisenbridge = { systemd.services.heisenbridge = {
description = "Matrix<->IRC bridge"; description = "Matrix<->IRC bridge";
requires = [ "matrix-conduit-nkagami.service" "matrix-synapse.service" ]; # So the registration file can be used by Synapse requires = [ "matrix-synapse.service" ]; # So the registration file can be used by Synapse
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
serviceConfig = rec { serviceConfig = rec {

View file

@ -4,7 +4,6 @@ let
cfg = config.cloud.gotosocial; cfg = config.cloud.gotosocial;
dbUser = "gotosocial"; dbUser = "gotosocial";
storageLocation = "/mnt/data/gotosocial";
in in
{ {
options.cloud.gotosocial = { options.cloud.gotosocial = {
@ -75,9 +74,6 @@ in
# Media # Media
media-emoji-remote-max-size = 256 * 1024 /* bytes */; media-emoji-remote-max-size = 256 * 1024 /* bytes */;
media-emoji-local-max-size = 256 * 1024 /* bytes */; media-emoji-local-max-size = 256 * 1024 /* bytes */;
media-remote-cache-days = 7;
media-cleanup-from = "00:00";
media-cleanup-every = "24h";
# OIDC # OIDC
oidc-enabled = true; oidc-enabled = true;
oidc-idp-name = "DTTH"; oidc-idp-name = "DTTH";
@ -86,22 +82,10 @@ in
http-client.block-ips = [ "11.0.0.0/24" ]; http-client.block-ips = [ "11.0.0.0/24" ];
# Advanced # Advanced
advanced-rate-limit-requests = 0; advanced-rate-limit-requests = 0;
# Storage
storage-backend = "local";
storage-local-base-path = "${storageLocation}/storage";
# instance-inject-mastodon-version = true; # instance-inject-mastodon-version = true;
}; };
}; };
systemd.services.gotosocial.requires = mkAfter [ "postgresql.service" "arion-authentik.service" ]; systemd.services.gotosocial.requires = mkAfter [ "minio.service" "postgresql.service" ];
systemd.services.gotosocial.after = mkAfter [ "postgresql.service" "arion-authentik.service" ]; systemd.services.gotosocial.after = mkAfter [ "minio.service" "postgresql.service" ];
systemd.services.gotosocial.unitConfig = {
RequiresMountsFor = [ storageLocation ];
ReadWritePaths = [ storageLocation ];
};
systemd.tmpfiles.settings."10-gotosocial".${storageLocation}.d = {
user = dbUser;
group = dbUser;
mode = "0700";
};
}; };
} }

View file

@ -1,183 +0,0 @@
commit 8c7f8c28fabc174a71499a4737579b24b5c4b244
Author: Natsu Kagami <nki@nkagami.me>
Date: Mon Oct 21 02:17:36 2024 +0200
Support R2
diff --git a/.env.sample b/.env.sample
index eb57ad85c..94ffcee07 100644
--- a/.env.sample
+++ b/.env.sample
@@ -66,6 +66,8 @@ AWS_S3_UPLOAD_BUCKET_URL=http://s3:4569
AWS_S3_UPLOAD_BUCKET_NAME=bucket_name_here
AWS_S3_FORCE_PATH_STYLE=true
AWS_S3_ACL=private
+AWS_S3_R2=true
+AWS_S3_R2_PUBLIC_URL=http://s3:4569
# AUTHENTICATION
diff --git a/app/utils/files.ts b/app/utils/files.ts
index 6607a6b12..5138f68ad 100644
--- a/app/utils/files.ts
+++ b/app/utils/files.ts
@@ -63,8 +63,13 @@ export const uploadFile = async (
xhr.addEventListener("loadend", () => {
resolve(xhr.readyState === 4 && xhr.status >= 200 && xhr.status < 400);
});
- xhr.open("POST", data.uploadUrl, true);
- xhr.send(formData);
+ xhr.open(data.method, data.uploadUrl, true);
+ xhr.setRequestHeader("Content-Type", file.type);
+ if (data.method === "POST") {
+ xhr.send(formData);
+ } else {
+ xhr.send(file);
+ }
});
if (!success) {
diff --git a/server/env.ts b/server/env.ts
index 5b420f2e1..4ea1e8d3c 100644
--- a/server/env.ts
+++ b/server/env.ts
@@ -519,6 +519,14 @@ export class Environment {
environment.AWS_S3_UPLOAD_BUCKET_NAME
);
+ @IsOptional()
+ public AWS_S3_R2 = this.toBoolean(environment.AWS_S3_R2 ?? "false");
+
+ @IsOptional()
+ public AWS_S3_R2_PUBLIC_URL = this.toOptionalString(
+ environment.AWS_S3_R2_PUBLIC_URL
+ );
+
/**
* Whether to force path style URLs for S3 objects, this is required for some
* S3-compatible storage providers.
diff --git a/server/routes/api/attachments/attachments.ts b/server/routes/api/attachments/attachments.ts
index 5e6c27594..b7620f440 100644
--- a/server/routes/api/attachments/attachments.ts
+++ b/server/routes/api/attachments/attachments.ts
@@ -3,6 +3,7 @@ import { v4 as uuidv4 } from "uuid";
import { AttachmentPreset } from "@shared/types";
import { bytesToHumanReadable } from "@shared/utils/files";
import { AttachmentValidation } from "@shared/validations";
+import env from "@server/env";
import { AuthorizationError, ValidationError } from "@server/errors";
import auth from "@server/middlewares/authentication";
import { rateLimiter } from "@server/middlewares/rateLimiter";
@@ -90,16 +91,30 @@ router.post(
{ transaction }
);
- const presignedPost = await FileStorage.getPresignedPost(
- key,
- acl,
- maxUploadSize,
- contentType
- );
+ let uploadUrl;
+ let method;
+ let presignedPost = {
+ fields: {},
+ };
+ if (env.AWS_S3_R2) {
+ uploadUrl = await FileStorage.getPresignedPut(key);
+ method = "PUT";
+ } else {
+ uploadUrl = FileStorage.getUploadUrl();
+ method = "POST";
+
+ presignedPost = await FileStorage.getPresignedPost(
+ key,
+ acl,
+ maxUploadSize,
+ contentType
+ );
+ }
ctx.body = {
data: {
- uploadUrl: FileStorage.getUploadUrl(),
+ uploadUrl,
+ method,
form: {
"Cache-Control": "max-age=31557600",
"Content-Type": contentType,
diff --git a/server/storage/files/BaseStorage.ts b/server/storage/files/BaseStorage.ts
index ce0287ebc..a1931c83d 100644
--- a/server/storage/files/BaseStorage.ts
+++ b/server/storage/files/BaseStorage.ts
@@ -26,6 +26,8 @@ export default abstract class BaseStorage {
contentType: string
): Promise<Partial<PresignedPost>>;
+ public abstract getPresignedPut(key: string): Promise<string>;
+
/**
* Returns a promise that resolves with a stream for reading a file from the storage provider.
*
diff --git a/server/storage/files/LocalStorage.ts b/server/storage/files/LocalStorage.ts
index 83cf98c50..324e60dd9 100644
--- a/server/storage/files/LocalStorage.ts
+++ b/server/storage/files/LocalStorage.ts
@@ -30,6 +30,10 @@ export default class LocalStorage extends BaseStorage {
});
}
+ public async getPresignedPut(key: string) {
+ return this.getUrlForKey(key);
+ }
+
public getUploadUrl() {
return "/api/files.create";
}
diff --git a/server/storage/files/S3Storage.ts b/server/storage/files/S3Storage.ts
index a42442e0c..d55ef5472 100644
--- a/server/storage/files/S3Storage.ts
+++ b/server/storage/files/S3Storage.ts
@@ -4,6 +4,7 @@ import {
S3Client,
DeleteObjectCommand,
GetObjectCommand,
+ PutObjectCommand,
ObjectCannedACL,
} from "@aws-sdk/client-s3";
import { Upload } from "@aws-sdk/lib-storage";
@@ -58,6 +59,16 @@ export default class S3Storage extends BaseStorage {
return createPresignedPost(this.client, params);
}
+ public async getPresignedPut(key: string) {
+ const params = {
+ Bucket: env.AWS_S3_UPLOAD_BUCKET_NAME,
+ Key: key,
+ };
+
+ const command = new PutObjectCommand(params);
+ return await getSignedUrl(this.client, command, { expiresIn: 3600 });
+ }
+
private getPublicEndpoint(isServerUpload?: boolean) {
if (env.AWS_S3_ACCELERATE_URL) {
return env.AWS_S3_ACCELERATE_URL;
@@ -137,10 +148,17 @@ export default class S3Storage extends BaseStorage {
);
}
+ public getR2ObjectUrl = async (key: string) =>
+ env.AWS_S3_R2_PUBLIC_URL + "/" + key;
+
public getSignedUrl = async (
key: string,
expiresIn = S3Storage.defaultSignedUrlExpires
) => {
+ if (env.AWS_S3_R2) {
+ return this.getR2ObjectUrl(key);
+ }
+
const isDocker = env.AWS_S3_UPLOAD_BUCKET_URL.match(/http:\/\/s3:/);
const params = {
Bucket: this.getBucket(),

View file

@ -316,11 +316,6 @@ in
programs.kdeconnect.enable = true; programs.kdeconnect.enable = true;
# Flatpaks are useful... sometimes... # Flatpaks are useful... sometimes...
services.flatpak.enable = true; services.flatpak.enable = true;
# AppImages should run
programs.appimage = {
enable = true;
binfmt = true;
};
# DConf for GNOME configurations # DConf for GNOME configurations
programs.dconf.enable = true; programs.dconf.enable = true;
# Gaming! (not for ARM64) # Gaming! (not for ARM64)

View file

@ -10,7 +10,7 @@ with lib;
ibm-plex ibm-plex
(nerdfonts.override { fonts = [ "NerdFontsSymbolsOnly" ]; }) (nerdfonts.override { fonts = [ "NerdFontsSymbolsOnly" ]; })
noto-fonts noto-fonts
(pkgs.noto-fonts-cjk-sans or pkgs.noto-fonts-cjk) noto-fonts-cjk
merriweather merriweather
corefonts corefonts
font-awesome font-awesome

View file

@ -24,11 +24,8 @@
./invidious.nix ./invidious.nix
./owncast.nix ./owncast.nix
./peertube.nix ./peertube.nix
./outline.nix
]; ];
system.stateVersion = "21.11";
common.linux.enable = false; # Don't enable the "common linux" module, this is a special machine. common.linux.enable = false; # Don't enable the "common linux" module, this is a special machine.
# Personal user # Personal user
@ -192,13 +189,74 @@
protocol = "udp"; protocol = "udp";
}; };
# Outline
sops.secrets.minio-secret-key = { owner = "root"; mode = "0444"; };
sops.secrets.authentik-oidc-client-secret = { owner = "outline"; };
sops.secrets."outline/smtp-password" = { owner = "outline"; };
services.outline = {
enable = true;
package = pkgs.outline.overrideAttrs (attrs: {
patches = if builtins.hasAttr "patches" attrs then attrs.patches else [ ] ++ [ ../modules/cloud/outline/dtth-wiki.patch ];
});
databaseUrl = "postgres://outline:outline@localhost/outline?sslmode=disable";
redisUrl = "local";
publicUrl = "https://wiki.dtth.ch";
port = 18729;
storage = {
accessKey = "minio";
secretKeyFile = config.sops.secrets.minio-secret-key.path;
region = config.services.minio.region;
uploadBucketUrl = "https://s3.dtth.ch";
uploadBucketName = "dtth-outline";
uploadMaxSize = 50 * 1024 * 1000;
};
maximumImportSize = 50 * 1024 * 1000;
oidcAuthentication = {
clientId = "3a0c10e00cdcb4a1194315577fa208a747c1a5f7";
clientSecretFile = config.sops.secrets.authentik-oidc-client-secret.path;
authUrl = "https://auth.dtth.ch/application/o/authorize/";
tokenUrl = "https://auth.dtth.ch/application/o/token/";
userinfoUrl = "https://auth.dtth.ch/application/o/userinfo/";
displayName = "DTTH Account";
};
smtp = {
fromEmail = "DTTH Wiki <dtth.wiki@nkagami.me>";
replyEmail = "";
host = "mx1.nkagami.me";
username = "dtth.wiki@nkagami.me";
passwordFile = config.sops.secrets."outline/smtp-password".path;
port = 465;
secure = true;
};
forceHttps = false;
};
cloud.postgresql.databases = [ "outline" ];
systemd.services.outline.requires = [ "postgresql.service" ];
cloud.traefik.hosts.outline = { host = "wiki.dtth.ch"; port = 18729; };
# GoToSocial # GoToSocial
sops.secrets.gts-env = { restartUnits = [ "gotosocial.service" ]; }; sops.secrets.gts-env = { };
cloud.gotosocial = { cloud.gotosocial = {
enable = true; enable = true;
envFile = config.sops.secrets.gts-env.path; envFile = config.sops.secrets.gts-env.path;
}; };
# Minio
sops.secrets.minio-credentials = { };
services.minio = {
enable = true;
listenAddress = ":61929";
consoleAddress = ":62929";
rootCredentialsFile = config.sops.secrets.minio-credentials.path;
dataDir = lib.mkForce [ "/mnt/data/minio" ];
};
cloud.traefik.hosts.minio = { host = "s3.dtth.ch"; port = 61929; };
system.stateVersion = "21.11";
# ntfy # ntfy
cloud.traefik.hosts.ntfy-sh = { host = "ntfy.nkagami.me"; port = 11161; noCloudflare = true; }; cloud.traefik.hosts.ntfy-sh = { host = "ntfy.nkagami.me"; port = 11161; noCloudflare = true; };
services.ntfy-sh = { services.ntfy-sh = {

View file

@ -98,7 +98,6 @@ in
}; };
users.groups.${user} = { }; users.groups.${user} = { };
sops.secrets."gitea/signing-key".owner = user; sops.secrets."gitea/signing-key".owner = user;
sops.secrets."gitea/minio-secret-key".owner = user;
sops.secrets."gitea/mailer-password".owner = user; sops.secrets."gitea/mailer-password".owner = user;
# database # database
cloud.postgresql.databases = [ user ]; cloud.postgresql.databases = [ user ];
@ -175,17 +174,6 @@ in
PATH = "${pkgs.git}/bin/git"; PATH = "${pkgs.git}/bin/git";
}; };
storage = {
STORAGE_TYPE = "minio";
MINIO_USE_SSL = "true";
MINIO_ENDPOINT = "60c0807121eb35ef52cdcd4a33735fa6.r2.cloudflarestorage.com";
MINIO_ACCESS_KEY_ID = "704c29ade7a8b438b77ab520da2799ca";
MINIO_SECRET_ACCESS_KEY = "#miniosecretkey#";
MINIO_BUCKET = "dtth-gitea";
MINIO_LOCATION = "auto";
MINIO_CHECKSUM_ALGORITHM = "md5"; # R2 moment
};
federation.ENABLED = true; federation.ENABLED = true;
DEFAULT.APP_NAME = "DTTHGit"; DEFAULT.APP_NAME = "DTTHGit";
}; };
@ -215,25 +203,17 @@ in
environment.GNUPGHOME = "${config.services.gitea.stateDir}/.gnupg"; environment.GNUPGHOME = "${config.services.gitea.stateDir}/.gnupg";
# https://github.com/NixOS/nixpkgs/commit/93c1d370db28ad4573fb9890c90164ba55391ce7 # https://github.com/NixOS/nixpkgs/commit/93c1d370db28ad4573fb9890c90164ba55391ce7
serviceConfig.SystemCallFilter = mkForce "~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @setuid @swap"; serviceConfig.SystemCallFilter = mkForce "~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @setuid @swap";
preStart = preStart = ''
let # Import the signing subkey
configFile = "${config.services.forgejo.customDir}/conf/app.ini"; if cat ${config.services.gitea.stateDir}/.gnupg/gpg.conf | grep -q ${signingKey}; then
in echo "Keys already imported"
'' # imported
# Update minio secret key else
chmod u+w ${configFile} && \ echo "Import your keys!"
${lib.getExe pkgs.replace-secret} '#miniosecretkey#' '${config.sops.secrets."gitea/minio-secret-key".path}' '${configFile}' && \ ${pkgs.gnupg}/bin/gpg --quiet --import ${secrets."gitea/signing-key".path}
chmod u-w ${configFile} echo "trusted-key ${signingKey}" >> ${config.services.gitea.stateDir}/.gnupg/gpg.conf
# Import the signing subkey exit 1
if cat ${config.services.forgejo.stateDir}/.gnupg/gpg.conf | grep -q ${signingKey}; then fi
echo "Keys already imported" '';
# imported
else
echo "Import your keys!"
${pkgs.gnupg}/bin/gpg --quiet --import ${secrets."gitea/signing-key".path}
echo "trusted-key ${signingKey}" >> ${config.services.forgejo.stateDir}/.gnupg/gpg.conf
exit 1
fi
'';
}; };
} }

View file

@ -9,11 +9,9 @@
swapDevices = [{ device = "/var/swapfile"; size = 4 * 1024; priority = 1024; }]; swapDevices = [{ device = "/var/swapfile"; size = 4 * 1024; priority = 1024; }];
zramSwap.enable = true; zramSwap.enable = true;
# volumes # volumes
services.btrfs.autoScrub.enable = true;
fileSystems.data = { fileSystems.data = {
device = "/dev/disk/by-id/scsi-0HC_Volume_101470796"; device = "/dev/disk/by-id/scsi-0HC_Volume_31812942";
fsType = "btrfs"; fsType = "ext4";
mountPoint = "/mnt/data"; mountPoint = "/mnt/data";
options = [ "compress=zstd" ];
}; };
} }

View file

@ -0,0 +1,67 @@
{ lib, pkgs, config, ... }:
with lib;
let
user = "nextcloud";
host = "cloud.dtth.ch";
port = 61155;
secrets = config.sops.secrets;
in
{
sops.secrets."nextcloud/admin-password" = { owner = user; };
sops.secrets."nextcloud/minio-secret-key" = { owner = user; key = "minio-secret-key"; };
# database
cloud.postgresql.databases = [ user ];
# traefik
cloud.traefik.hosts.nextcloud = {
inherit port host;
};
systemd.services.nextcloud.requires = [ "postgresql.service" ];
services.nextcloud = {
enable = true;
hostName = host;
package = pkgs.nextcloud26;
enableBrokenCiphersForSSE = false;
home = "/mnt/data/nextcloud";
https = true;
database.createLocally = false;
extraApps = with pkgs.nextcloud26Packages.apps; {
inherit calendar contacts deck forms groupfolders news tasks;
sociallogin = pkgs.fetchNextcloudApp rec {
url = "https://github.com/zorn-v/nextcloud-social-login/releases/download/v5.4.3/release.tar.gz";
sha256 = "sha256-ZKwtF9j9WFIk3MZgng9DmN00A73S2Rb4qbehL9adaZo=";
};
};
config = {
# Database
dbtype = "pgsql";
dbname = user;
dbuser = user;
dbhost = "/run/postgresql";
# User
adminuser = "nki";
adminpassFile = secrets."nextcloud/admin-password".path;
# General
overwriteProtocol = "https";
defaultPhoneRegion = "VN";
objectstore.s3 = {
enable = true;
bucket = "nextcloud-dtth";
autocreate = true;
key = "minio";
secretFile = config.sops.secrets."nextcloud/minio-secret-key".path;
hostname = "s3.dtth.ch";
port = 443;
useSsl = true;
usePathStyle = true;
region = "us-east-1";
};
};
};
services.nginx.virtualHosts.${host}.listen = [{ inherit port; addr = "127.0.0.1"; }];
}

View file

@ -1,56 +0,0 @@
{ config, pkgs, ... }: {
sops.secrets.authentik-oidc-client-secret = { owner = "outline"; };
sops.secrets."outline/smtp-password" = { owner = "outline"; };
sops.secrets."outline/s3-secret-key" = { owner = "outline"; };
services.outline = {
enable = true;
package = pkgs.outline.overrideAttrs (attrs: {
patches = attrs.patches or [ ] ++ [
../modules/cloud/outline/dtth-wiki.patch
../modules/cloud/outline/r2.patch
];
});
databaseUrl = "postgres://outline:outline@localhost/outline?sslmode=disable";
redisUrl = "local";
publicUrl = "https://wiki.dtth.ch";
port = 18729;
storage = {
accessKey = "6ef730e13f172d2ed6ed77f0b5b9bad9";
secretKeyFile = config.sops.secrets."outline/s3-secret-key".path;
region = "auto";
uploadBucketUrl = "https://60c0807121eb35ef52cdcd4a33735fa6.r2.cloudflarestorage.com";
uploadBucketName = "dtth-outline";
uploadMaxSize = 50 * 1024 * 1000;
};
maximumImportSize = 50 * 1024 * 1000;
oidcAuthentication = {
clientId = "3a0c10e00cdcb4a1194315577fa208a747c1a5f7";
clientSecretFile = config.sops.secrets.authentik-oidc-client-secret.path;
authUrl = "https://auth.dtth.ch/application/o/authorize/";
tokenUrl = "https://auth.dtth.ch/application/o/token/";
userinfoUrl = "https://auth.dtth.ch/application/o/userinfo/";
displayName = "DTTH Account";
};
smtp = {
fromEmail = "DTTH Wiki <dtth.wiki@nkagami.me>";
replyEmail = "";
host = "mx1.nkagami.me";
username = "dtth.wiki@nkagami.me";
passwordFile = config.sops.secrets."outline/smtp-password".path;
port = 465;
secure = true;
};
forceHttps = false;
};
cloud.postgresql.databases = [ "outline" ];
systemd.services.outline.requires = [ "postgresql.service" ];
systemd.services.outline.environment = {
AWS_S3_R2 = "true";
AWS_S3_R2_PUBLIC_URL = "https://s3.wiki.dtth.ch";
};
cloud.traefik.hosts.outline = { host = "wiki.dtth.ch"; port = 18729; };
}

File diff suppressed because one or more lines are too long

View file

@ -25,7 +25,7 @@ let
overlay-versioning = final: prev: { overlay-versioning = final: prev: {
gotosocial = prev.gotosocial.overrideAttrs (attrs: rec { gotosocial = prev.gotosocial.overrideAttrs (attrs: rec {
version = "0.17.1"; version = "0.17.0-rc3";
ldflags = [ ldflags = [
"-s" "-s"
"-w" "-w"
@ -35,13 +35,13 @@ let
web-assets = final.fetchurl { web-assets = final.fetchurl {
url = "https://github.com/superseriousbusiness/gotosocial/releases/download/v${version}/gotosocial_${version}_web-assets.tar.gz"; url = "https://github.com/superseriousbusiness/gotosocial/releases/download/v${version}/gotosocial_${version}_web-assets.tar.gz";
hash = "sha256-rGntLlIbgfCtdqpD7tnvAY8qwF+BpYbQWfAGMhdOTgY="; hash = "sha256-Uwltr5syOnDZOgMc2L/iedxiMMKXmULzm0SAs3W0SXQ=";
}; };
src = final.fetchFromGitHub { src = final.fetchFromGitHub {
owner = "superseriousbusiness"; owner = "superseriousbusiness";
repo = "gotosocial"; repo = "gotosocial";
rev = "v${version}"; rev = "v${version}";
hash = "sha256-oWWsCs9jgd244yzWhgLkuHp7kY0BQ8+Ay6KpuBVG+U8="; hash = "sha256-c7CJFQWTMCBZuzI/Mf5PJuCWY1NKW4LLMAJem3TTJvM=";
}; };
postInstall = '' postInstall = ''
tar xf ${web-assets} tar xf ${web-assets}
@ -87,6 +87,13 @@ let
}) })
]; ];
}; };
# https://github.com/NixOS/nixpkgs/issues/334822
vulkan-validation-layers = prev.vulkan-validation-layers.overrideAttrs (attrs: {
buildInputs = attrs.buildInputs ++ [
final.spirv-tools
];
});
}; };
overlay-libs = final: prev: { overlay-libs = final: prev: {
@ -109,10 +116,6 @@ let
meta.mainProgram = "kak-lsp"; meta.mainProgram = "kak-lsp";
}; };
zen-browser-bin = final.callPackage ./packages/x86_64-linux/zen-browser-bin.nix {
nativeMessagingHosts = with final; [ kdePackages.plasma-browser-integration ];
};
}; };
overlay-rust-is-dumb = final: prev: { overlay-rust-is-dumb = final: prev: {

View file

@ -1,32 +0,0 @@
{ appimageTools, fetchurl, nativeMessagingHosts ? [ ], ... }:
let
pname = "zen-browser-bin";
version = "1.0.1-a.19";
src = fetchurl {
url = "https://github.com/zen-browser/desktop/releases/download/${version}/zen-specific.AppImage";
hash = "sha256-qAPZ4VyVmeZLRfL0kPHF75zyrSUFHKQUSUcpYKs3jk8=";
};
appimageContents = appimageTools.extract {
inherit pname version src;
};
in
appimageTools.wrapType2 {
inherit pname version src;
extraInstallCommands = ''
mv $out/bin/${pname} $out/bin/zen
install -m 444 -D ${appimageContents}/zen.desktop $out/share/applications/zen.desktop
install -m 444 -D ${appimageContents}/usr/share/icons/hicolor/128x128/apps/zen.png \
$out/share/icons/hicolor/128x128/apps/zen.png
mkdir -p $out/lib/mozilla/native-messaging-hosts
for ext in ${toString nativeMessagingHosts}; do
ln -sLt $out/lib/mozilla/native-messaging-hosts $ext/lib/mozilla/native-messaging-hosts/*
done
'';
meta.mainProgram = "zen";
}