feat: add mastodon module

This commit is contained in:
Kiana Sheibani 2025-04-02 05:55:01 -04:00
parent c0a33e111a
commit b66ac7683b
Signed by: toki
GPG key ID: 6CB106C25E86A9F7
5 changed files with 146 additions and 3 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

@ -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.
'';
};
};
};
}