Compare commits

...

3 commits

Author SHA1 Message Date
Kiana Sheibani 69cefa7261
chore: bump inputs 2025-04-02 05:56:55 -04:00
Kiana Sheibani b66ac7683b
feat: add mastodon module 2025-04-02 05:55:10 -04:00
Kiana Sheibani c0a33e111a
fix: always require ACME email 2025-04-02 05:52:23 -04:00
8 changed files with 160 additions and 20 deletions

View file

@ -31,14 +31,28 @@ module has options, they can be found in the `options.nix` file inside the
module directory. More general options used by multiple modules are documented
in `modules/options.nix`.
### Module Checklist
### Modules
Modules listed here may be unimplemented or unfinished.
#### Basic
- [x] `basic` - Basic Internet support
- [x] `ssh` - SSH support
- [ ] `site` - Static site hosting
- [x] `fail2ban` - IP moderation
#### Public Sites
- [ ] `site` - Static site hosting
- [x] `forgejo` - Code forge
#### Social
- [x] `mastodon` - Mastodon server instance
- [ ] `mail` - Mail server
#### Storage
- [ ] `cachix` - Nix build caching
- [ ] `backup` - Automated backup system

View file

@ -1,4 +1,4 @@
{ config, lib, pkgs, aether, forgejo-tokyo-night, ... }:
{ pkgs, aether, forgejo-tokyo-night, ... }:
{
networking.hostName = "toki-aether";
time.timeZone = "America/New_York";
@ -65,5 +65,14 @@
federation.ENABLED = true;
};
aether.mastodon.subdomain = "social";
services.mastodon = {
package = pkgs.mastodon.override {
patches = [ ./mastodon/increase_limits.patch ];
};
extraConfig.SINGLE_USER_MODE = "true";
streamingProcesses = 3;
};
system.stateVersion = "24.05";
}

View file

@ -0,0 +1,41 @@
diff --git a/app/javascript/mastodon/features/compose/containers/compose_form_container.js b/app/javascript/mastodon/features/compose/containers/compose_form_container.js
index bda2edb..1be1ce2 100644
--- a/app/javascript/mastodon/features/compose/containers/compose_form_container.js
+++ b/app/javascript/mastodon/features/compose/containers/compose_form_container.js
@@ -28,7 +28,7 @@ const mapStateToProps = state => ({
anyMedia: state.getIn(['compose', 'media_attachments']).size > 0,
isInReply: state.getIn(['compose', 'in_reply_to']) !== null,
lang: state.getIn(['compose', 'language']),
- maxChars: state.getIn(['server', 'server', 'configuration', 'statuses', 'max_characters'], 500),
+ maxChars: state.getIn(['server', 'server', 'configuration', 'statuses', 'max_characters'], 1000000),
});
const mapDispatchToProps = (dispatch) => ({
diff --git a/app/validators/poll_validator.rb b/app/validators/poll_validator.rb
index a327277..5d3134d 100644
--- a/app/validators/poll_validator.rb
+++ b/app/validators/poll_validator.rb
@@ -1,8 +1,8 @@
# frozen_string_literal: true
class PollValidator < ActiveModel::Validator
- MAX_OPTIONS = 4
- MAX_OPTION_CHARS = 50
+ MAX_OPTIONS = 100
+ MAX_OPTION_CHARS = 1000
MAX_EXPIRATION = 1.month.freeze
MIN_EXPIRATION = 5.minutes.freeze
diff --git a/app/validators/status_length_validator.rb b/app/validators/status_length_validator.rb
index dc841de..f0f1b25 100644
--- a/app/validators/status_length_validator.rb
+++ b/app/validators/status_length_validator.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
class StatusLengthValidator < ActiveModel::Validator
- MAX_CHARS = 500
+ MAX_CHARS = 1000000
URL_PLACEHOLDER_CHARS = 23
URL_PLACEHOLDER = 'x' * 23

View file

@ -10,11 +10,11 @@
"systems": "systems"
},
"locked": {
"lastModified": 1723293904,
"narHash": "sha256-b+uqzj+Wa6xgMS9aNbX4I+sXeb5biPDi39VgvSFqFvU=",
"lastModified": 1736955230,
"narHash": "sha256-uenf8fv2eG5bKM8C/UvFaiJMZ4IpUFaQxk9OH5t/1gA=",
"owner": "ryantm",
"repo": "agenix",
"rev": "f6291c5935fdc4e0bef208cfc0dcab7e3f7a1c41",
"rev": "e600439ec4c273cf11e06fe4d9d906fb98fa097c",
"type": "github"
},
"original": {
@ -74,11 +74,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1736344531,
"narHash": "sha256-8YVQ9ZbSfuUk2bUf2KRj60NRraLPKPS0Q4QFTbc+c2c=",
"lastModified": 1743448293,
"narHash": "sha256-bmEPmSjJakAp/JojZRrUvNcDX2R5/nuX6bm+seVaGhs=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "bffc22eb12172e6db3c5dde9e3e5628f8e3e7912",
"rev": "77b584d61ff80b4cef9245829a6f1dfad5afdfa3",
"type": "github"
},
"original": {

View file

@ -1,4 +1,4 @@
args@{ config, lib, ... }:
{ config, lib, ... }:
{
imports = [ ../options.nix ];
@ -49,11 +49,4 @@ args@{ config, lib, ... }:
};
};
};
config.assertions = lib.mkIf config.aether.https [
{
assertion = !(builtins.isNull config.aether.acmeEmail);
message = "HTTPS support requires providing a contact email";
}
];
}

View file

@ -0,0 +1,37 @@
{ config, lib, ... }:
let
cfg = config.aether.mastodon;
mastodon = config.services.mastodon;
useSubdomain = !(builtins.isNull cfg.subdomain);
domain = lib.optionalString useSubdomain "${cfg.subdomain}."
+ config.aether.domain;
in {
imports = [ ./options.nix ];
services.mastodon = {
enable = true;
user = cfg.user;
group = mastodon.user;
localDomain = domain;
configureNginx = true;
smtp.fromAddress = cfg.email;
};
security.acme.acceptTerms = true;
security.acme.defaults.email = config.aether.acmeEmail;
networking.firewall.allowedTCPPorts = [ 80 443 ];
users.users = lib.mkIf (cfg.createUser && mastodon.user != "mastodon") {
${mastodon.user} = {
home = mastodon.package;
useDefaultShell = true;
group = mastodon.group;
isSystemUser = true;
};
};
users.groups = lib.mkIf (cfg.createUser && mastodon.group != "mastodon") {
${mastodon.group} = {};
};
}

View file

@ -0,0 +1,42 @@
{ config, lib, ... }:
{
imports = [ ../options.nix ];
options.aether = {
mastodon = {
subdomain = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = "mastodon";
description = ''
The subdomain to host Mastodon under.
If null, then Mastodon is hosted at the domain itself.
'';
};
user = lib.mkOption {
type = lib.types.str;
default = "mastodon";
description = ''
The user to run Mastodon with.
'';
};
createUser = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Whether to create the Mastodon user automatically.
'';
};
email = lib.mkOption {
type = lib.types.str;
default = config.aether.acmeEmail;
description = ''
The email address used by Mastodon to send emails from.
'';
};
};
};
}

View file

@ -9,13 +9,17 @@
https = lib.mkOption {
type = lib.types.boolByOr;
default = true;
description = "Whether to force HTTPS connections for websites.";
description = ''
Whether to force HTTPS connections for websites.
This option is ignored if the service strictly requires HTTPS.
'';
};
acmeEmail = lib.mkOption {
type = lib.types.nullOr lib.types.str;
type = lib.types.str;
default = null;
description = "Email address for ACME.";
description = "Email address to provide to the ACME service.";
};
};
}