mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-04-13 20:37:37 +00:00
Merge pull request #251687 from martinetd/cryptpad
nixos/cryptpad: init, cryptpad: init at 2024.6.0
This commit is contained in:
commit
ceda66b310
@ -48,6 +48,8 @@
|
||||
|
||||
- [Localsend](https://localsend.org/), an open source cross-platform alternative to AirDrop. Available as [programs.localsend](#opt-programs.localsend.enable).
|
||||
|
||||
- [cryptpad](https://cryptpad.org/), a privacy-oriented collaborative platform (docs/drive/etc), has been added back. Available as [services.cryptpad](#opt-services.cryptpad.enable).
|
||||
|
||||
- [realm](https://github.com/zhboner/realm), a simple, high performance relay server written in rust. Available as [services.realm.enable](#opt-services.realm.enable).
|
||||
|
||||
- [Gotenberg](https://gotenberg.dev), an API server for converting files to PDFs that can be used alongside Paperless-ngx. Available as [services.gotenberg](options.html#opt-services.gotenberg).
|
||||
|
@ -1378,6 +1378,7 @@
|
||||
./services/web-apps/convos.nix
|
||||
./services/web-apps/crabfit.nix
|
||||
./services/web-apps/davis.nix
|
||||
./services/web-apps/cryptpad.nix
|
||||
./services/web-apps/dex.nix
|
||||
./services/web-apps/discourse.nix
|
||||
./services/web-apps/documize.nix
|
||||
|
@ -117,7 +117,6 @@ in
|
||||
(mkRemovedOptionModule [ "services" "virtuoso" ] "The corresponding package was removed from nixpkgs.")
|
||||
(mkRemovedOptionModule [ "services" "openfire" ] "The corresponding package was removed from nixpkgs.")
|
||||
(mkRemovedOptionModule [ "services" "riak" ] "The corresponding package was removed from nixpkgs.")
|
||||
(mkRemovedOptionModule [ "services" "cryptpad" ] "The corresponding package was removed from nixpkgs.")
|
||||
(mkRemovedOptionModule [ "services" "rtsp-simple-server" ] "Package has been completely rebranded by upstream as mediamtx, and thus the service and the package were renamed in NixOS as well.")
|
||||
(mkRemovedOptionModule [ "services" "prayer" ] "The corresponding package was removed from nixpkgs.")
|
||||
(mkRemovedOptionModule [ "services" "restya-board" ] "The corresponding package was removed from nixpkgs.")
|
||||
|
293
nixos/modules/services/web-apps/cryptpad.nix
Normal file
293
nixos/modules/services/web-apps/cryptpad.nix
Normal file
@ -0,0 +1,293 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
cfg = config.services.cryptpad;
|
||||
|
||||
inherit (lib)
|
||||
mkIf
|
||||
mkMerge
|
||||
mkOption
|
||||
strings
|
||||
types
|
||||
;
|
||||
|
||||
# The Cryptpad configuration file isn't JSON, but a JavaScript source file that assigns a JSON value
|
||||
# to a variable.
|
||||
cryptpadConfigFile = builtins.toFile "cryptpad_config.js" ''
|
||||
module.exports = ${builtins.toJSON cfg.settings}
|
||||
'';
|
||||
|
||||
# Derive domain names for Nginx configuration from Cryptpad configuration
|
||||
mainDomain = strings.removePrefix "https://" cfg.settings.httpUnsafeOrigin;
|
||||
sandboxDomain =
|
||||
if cfg.settings.httpSafeOrigin == null then
|
||||
mainDomain
|
||||
else
|
||||
strings.removePrefix "https://" cfg.settings.httpSafeOrigin;
|
||||
|
||||
in
|
||||
{
|
||||
options.services.cryptpad = {
|
||||
enable = lib.mkEnableOption "cryptpad";
|
||||
|
||||
package = lib.mkPackageOption pkgs "cryptpad" { };
|
||||
|
||||
configureNginx = mkOption {
|
||||
description = ''
|
||||
Configure Nginx as a reverse proxy for Cryptpad.
|
||||
Note that this makes some assumptions on your setup, and sets settings that will
|
||||
affect other virtualHosts running on your Nginx instance, if any.
|
||||
Alternatively you can configure a reverse-proxy of your choice.
|
||||
'';
|
||||
type = types.bool;
|
||||
default = false;
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
description = ''
|
||||
Cryptpad configuration settings.
|
||||
See https://github.com/cryptpad/cryptpad/blob/main/config/config.example.js for a more extensive
|
||||
reference documentation.
|
||||
Test your deployed instance through `https://<domain>/checkup/`.
|
||||
'';
|
||||
type = types.submodule {
|
||||
freeformType = (pkgs.formats.json { }).type;
|
||||
options = {
|
||||
httpUnsafeOrigin = mkOption {
|
||||
type = types.str;
|
||||
example = "https://cryptpad.example.com";
|
||||
default = "";
|
||||
description = "This is the URL that users will enter to load your instance";
|
||||
};
|
||||
httpSafeOrigin = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
example = "https://cryptpad-ui.example.com. Apparently optional but recommended.";
|
||||
description = "Cryptpad sandbox URL";
|
||||
};
|
||||
httpAddress = mkOption {
|
||||
type = types.str;
|
||||
default = "127.0.0.1";
|
||||
description = "Address on which the Node.js server should listen";
|
||||
};
|
||||
httpPort = mkOption {
|
||||
type = types.int;
|
||||
default = 3000;
|
||||
description = "Port on which the Node.js server should listen";
|
||||
};
|
||||
websocketPort = mkOption {
|
||||
type = types.int;
|
||||
default = 3003;
|
||||
description = "Port for the websocket that needs to be separate";
|
||||
};
|
||||
maxWorkers = mkOption {
|
||||
type = types.nullOr types.int;
|
||||
default = null;
|
||||
description = "Number of child processes, defaults to number of cores available";
|
||||
};
|
||||
adminKeys = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
description = "List of public signing keys of users that can access the admin panel";
|
||||
example = [ "[cryptpad-user1@my.awesome.website/YZgXQxKR0Rcb6r6CmxHPdAGLVludrAF2lEnkbx1vVOo=]" ];
|
||||
};
|
||||
logToStdout = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Controls whether log output should go to stdout of the systemd service";
|
||||
};
|
||||
logLevel = mkOption {
|
||||
type = types.str;
|
||||
default = "info";
|
||||
description = "Controls log level";
|
||||
};
|
||||
blockDailyCheck = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Disable telemetry. This setting is only effective if the 'Disable server telemetry'
|
||||
setting in the admin menu has been untouched, and will be ignored by cryptpad once
|
||||
that option is set either way.
|
||||
Note that due to the service confinement, just enabling the option in the admin
|
||||
menu will not be able to resolve DNS and fail; this setting must be set as well.
|
||||
'';
|
||||
};
|
||||
installMethod = mkOption {
|
||||
type = types.str;
|
||||
default = "nixos";
|
||||
description = ''
|
||||
Install method is listed in telemetry if you agree to it through the consentToContact
|
||||
setting in the admin panel.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable (mkMerge [
|
||||
{
|
||||
systemd.services.cryptpad = {
|
||||
description = "Cryptpad service";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "networking.target" ];
|
||||
serviceConfig = {
|
||||
BindReadOnlyPaths = [
|
||||
cryptpadConfigFile
|
||||
# apparently needs proc for workers management
|
||||
"/proc"
|
||||
"/dev/urandom"
|
||||
];
|
||||
DynamicUser = true;
|
||||
Environment = [
|
||||
"CRYPTPAD_CONFIG=${cryptpadConfigFile}"
|
||||
"HOME=%S/cryptpad"
|
||||
];
|
||||
ExecStart = lib.getExe cfg.package;
|
||||
Restart = "always";
|
||||
StateDirectory = "cryptpad";
|
||||
WorkingDirectory = "%S/cryptpad";
|
||||
# security way too many numerous options, from the systemd-analyze security output
|
||||
# at end of test: block everything except
|
||||
# - SystemCallFiters=@resources is required for node
|
||||
# - MemoryDenyWriteExecute for node JIT
|
||||
# - RestrictAddressFamilies=~AF_(INET|INET6) / PrivateNetwork to bind to sockets
|
||||
# - IPAddressDeny likewise allow localhost if binding to localhost or any otherwise
|
||||
# - PrivateUsers somehow service doesn't start with that
|
||||
# - DeviceAllow (char-rtc r added by ProtectClock)
|
||||
AmbientCapabilities = "";
|
||||
CapabilityBoundingSet = "";
|
||||
DeviceAllow = "";
|
||||
LockPersonality = true;
|
||||
NoNewPrivileges = true;
|
||||
PrivateDevices = true;
|
||||
PrivateTmp = true;
|
||||
ProcSubset = "pid";
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectProc = "invisible";
|
||||
ProtectSystem = "strict";
|
||||
RemoveIPC = true;
|
||||
RestrictAddressFamilies = [
|
||||
"AF_INET"
|
||||
"AF_INET6"
|
||||
];
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
RuntimeDirectoryMode = "700";
|
||||
SocketBindAllow = [
|
||||
"tcp:${builtins.toString cfg.settings.httpPort}"
|
||||
"tcp:${builtins.toString cfg.settings.websocketPort}"
|
||||
];
|
||||
SocketBindDeny = [ "any" ];
|
||||
StateDirectoryMode = "0700";
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = [
|
||||
"@pkey"
|
||||
"@system-service"
|
||||
"~@chown"
|
||||
"~@keyring"
|
||||
"~@memlock"
|
||||
"~@privileged"
|
||||
"~@resources"
|
||||
"~@setuid"
|
||||
"~@timer"
|
||||
];
|
||||
UMask = "0077";
|
||||
};
|
||||
confinement = {
|
||||
enable = true;
|
||||
binSh = null;
|
||||
mode = "chroot-only";
|
||||
};
|
||||
};
|
||||
}
|
||||
# block external network access if not phoning home and
|
||||
# binding to localhost (default)
|
||||
(mkIf
|
||||
(
|
||||
cfg.settings.blockDailyCheck
|
||||
&& (builtins.elem cfg.settings.httpAddress [
|
||||
"127.0.0.1"
|
||||
"::1"
|
||||
])
|
||||
)
|
||||
{
|
||||
systemd.services.cryptpad = {
|
||||
serviceConfig = {
|
||||
IPAddressAllow = [ "localhost" ];
|
||||
IPAddressDeny = [ "any" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
# .. conversely allow DNS & TLS if telemetry is explicitly enabled
|
||||
(mkIf (!cfg.settings.blockDailyCheck) {
|
||||
systemd.services.cryptpad = {
|
||||
serviceConfig = {
|
||||
BindReadOnlyPaths = [
|
||||
"-/etc/resolv.conf"
|
||||
"-/run/systemd"
|
||||
"/etc/hosts"
|
||||
"/etc/ssl/certs/ca-certificates.crt"
|
||||
];
|
||||
};
|
||||
};
|
||||
})
|
||||
|
||||
(mkIf cfg.configureNginx {
|
||||
assertions = [
|
||||
{
|
||||
assertion = cfg.settings.httpUnsafeOrigin != "";
|
||||
message = "services.cryptpad.settings.httpUnsafeOrigin is required";
|
||||
}
|
||||
{
|
||||
assertion = strings.hasPrefix "https://" cfg.settings.httpUnsafeOrigin;
|
||||
message = "services.cryptpad.settings.httpUnsafeOrigin must start with https://";
|
||||
}
|
||||
{
|
||||
assertion =
|
||||
cfg.settings.httpSafeOrigin == null || strings.hasPrefix "https://" cfg.settings.httpSafeOrigin;
|
||||
message = "services.cryptpad.settings.httpSafeOrigin must start with https:// (or be unset)";
|
||||
}
|
||||
];
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
recommendedTlsSettings = true;
|
||||
recommendedProxySettings = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedGzipSettings = true;
|
||||
|
||||
virtualHosts = mkMerge [
|
||||
{
|
||||
"${mainDomain}" = {
|
||||
serverAliases = lib.optionals (cfg.settings.httpSafeOrigin != null) [ sandboxDomain ];
|
||||
enableACME = lib.mkDefault true;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://${cfg.settings.httpAddress}:${builtins.toString cfg.settings.httpPort}";
|
||||
extraConfig = ''
|
||||
client_max_body_size 150m;
|
||||
'';
|
||||
};
|
||||
locations."/cryptpad_websocket" = {
|
||||
proxyPass = "http://${cfg.settings.httpAddress}:${builtins.toString cfg.settings.websocketPort}";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
})
|
||||
]);
|
||||
}
|
@ -235,6 +235,7 @@ in {
|
||||
couchdb = handleTest ./couchdb.nix {};
|
||||
crabfit = handleTest ./crabfit.nix {};
|
||||
cri-o = handleTestOn ["aarch64-linux" "x86_64-linux"] ./cri-o.nix {};
|
||||
cryptpad = runTest ./cryptpad.nix;
|
||||
cups-pdf = handleTest ./cups-pdf.nix {};
|
||||
curl-impersonate = handleTest ./curl-impersonate.nix {};
|
||||
custom-ca = handleTest ./custom-ca.nix {};
|
||||
|
71
nixos/tests/cryptpad.nix
Normal file
71
nixos/tests/cryptpad.nix
Normal file
@ -0,0 +1,71 @@
|
||||
{ pkgs, ... }:
|
||||
let
|
||||
certs = pkgs.runCommand "cryptpadSelfSignedCerts" { buildInputs = [ pkgs.openssl ]; } ''
|
||||
mkdir -p $out
|
||||
cd $out
|
||||
openssl req -x509 -newkey rsa:4096 \
|
||||
-keyout key.pem -out cert.pem -nodes -days 3650 \
|
||||
-subj '/CN=cryptpad.localhost' \
|
||||
-addext 'subjectAltName = DNS.1:cryptpad.localhost, DNS.2:cryptpad-sandbox.localhost'
|
||||
'';
|
||||
# data sniffed from cryptpad's /checkup network trace, seems to be re-usable
|
||||
test_write_data = pkgs.writeText "cryptpadTestData" ''
|
||||
{"command":"WRITE_BLOCK","content":{"publicKey":"O2onvM62pC1io6jQKm8Nc2UyFXcd4kOmOsBIoYtZ2ik=","signature":"aXcM9SMO59lwA7q7HbYB+AnzymmxSyy/KhkG/cXIBVzl8v+kkPWXmFuWhcuKfRF8yt3Zc3ktIsHoFyuyDSAwAA==","ciphertext":"AFwCIfBHKdFzDKjMg4cu66qlJLpP+6Yxogbl3o9neiQou5P8h8yJB8qgnQ=="},"publicKey":"O2onvM62pC1io6jQKm8Nc2UyFXcd4kOmOsBIoYtZ2ik=","nonce":"bitSbJMNSzOsg98nEzN80a231PCkBQeH"}
|
||||
'';
|
||||
in
|
||||
{
|
||||
name = "cryptpad";
|
||||
meta = with pkgs.lib.maintainers; {
|
||||
maintainers = [ martinetd ];
|
||||
};
|
||||
|
||||
nodes.machine = {
|
||||
services.cryptpad = {
|
||||
enable = true;
|
||||
configureNginx = true;
|
||||
settings = {
|
||||
httpUnsafeOrigin = "https://cryptpad.localhost";
|
||||
httpSafeOrigin = "https://cryptpad-sandbox.localhost";
|
||||
};
|
||||
};
|
||||
services.nginx = {
|
||||
virtualHosts."cryptpad.localhost" = {
|
||||
enableACME = false;
|
||||
sslCertificate = "${certs}/cert.pem";
|
||||
sslCertificateKey = "${certs}/key.pem";
|
||||
};
|
||||
};
|
||||
security = {
|
||||
pki.certificateFiles = [ "${certs}/cert.pem" ];
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
machine.wait_for_unit("cryptpad.service")
|
||||
machine.wait_for_unit("nginx.service")
|
||||
machine.wait_for_open_port(3000)
|
||||
|
||||
# test home page
|
||||
machine.succeed("curl --fail https://cryptpad.localhost -o /tmp/cryptpad_home.html")
|
||||
machine.succeed("grep -F 'CryptPad: Collaboration suite' /tmp/cryptpad_home.html")
|
||||
|
||||
# test scripts/build.js actually generated customize content from config
|
||||
machine.succeed("grep -F 'meta property=\"og:url\" content=\"https://cryptpad.localhost/index.html' /tmp/cryptpad_home.html")
|
||||
|
||||
# make sure child pages are accessible (e.g. check nginx try_files paths)
|
||||
machine.succeed(
|
||||
"grep -oE '/(customize|components)[^\"]*' /tmp/cryptpad_home.html"
|
||||
" | while read -r page; do"
|
||||
" curl -O --fail https://cryptpad.localhost$page || exit;"
|
||||
" done")
|
||||
|
||||
# test some API (e.g. check cryptpad main process)
|
||||
machine.succeed("curl --fail -d @${test_write_data} -H 'Content-Type: application/json' https://cryptpad.localhost/api/auth")
|
||||
|
||||
# test telemetry has been disabled
|
||||
machine.fail("journalctl -u cryptpad | grep TELEMETRY");
|
||||
|
||||
# for future improvements
|
||||
machine.log(machine.execute("systemd-analyze security cryptpad.service")[1])
|
||||
'';
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
From 4bf0be64fe51a9c9fd9e410ada15251378b743bf Mon Sep 17 00:00:00 2001
|
||||
From: Dominique Martinet <asmadeus@codewreck.org>
|
||||
Date: Sat, 26 Aug 2023 09:28:59 +0900
|
||||
Subject: [PATCH] env.js: fix httpSafePort handling
|
||||
|
||||
It has been clarified that this is only a dev option that should not be
|
||||
used in production, but setting the value in config was still ignored,
|
||||
so fix the init code to consider the config value and make it clear that
|
||||
this port is not bound if safeOrigin is set.
|
||||
---
|
||||
config/config.example.js | 3 ++-
|
||||
lib/env.js | 5 +++--
|
||||
2 files changed, 5 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/config/config.example.js b/config/config.example.js
|
||||
index 7c8184c6c2f6..77263643c354 100644
|
||||
--- a/config/config.example.js
|
||||
+++ b/config/config.example.js
|
||||
@@ -89,8 +89,9 @@ module.exports = {
|
||||
|
||||
/* httpSafePort purpose is to emulate another origin for the sandbox when
|
||||
* you don't have two domains at hand (i.e. when httpSafeOrigin not defined).
|
||||
- * It is meant to be used only in case where you are working on a local
|
||||
+ * It is meant to be used only in case where you are working on a local
|
||||
* development instance. The default value is your httpPort + 1.
|
||||
+ * Setting this to 0 or setting httpSafeOrigin disables this listener.
|
||||
*
|
||||
*/
|
||||
//httpSafePort: 3001,
|
||||
diff --git a/lib/env.js b/lib/env.js
|
||||
index d3748750f21e..f0660cba3e11 100644
|
||||
--- a/lib/env.js
|
||||
+++ b/lib/env.js
|
||||
@@ -74,8 +74,9 @@ module.exports.create = function (config) {
|
||||
|
||||
if (typeof(config.httpSafeOrigin) !== 'string') {
|
||||
NO_SANDBOX = true;
|
||||
- if (typeof(config.httpSafePort) !== 'number') { httpSafePort = httpPort + 1; }
|
||||
httpSafeOrigin = deriveSandboxOrigin(httpUnsafeOrigin, httpSafePort);
|
||||
+ // only set if httpSafeOrigin isn't set.
|
||||
+ httpSafePort = isValidPort(config.httpSafePort) ? config.httpSafePort : (httpPort + 1);
|
||||
} else {
|
||||
httpSafeOrigin = canonicalizeOrigin(config.httpSafeOrigin);
|
||||
}
|
||||
@@ -115,7 +116,7 @@ module.exports.create = function (config) {
|
||||
permittedEmbedders: typeof(permittedEmbedders) === 'string' && permittedEmbedders? permittedEmbedders: httpSafeOrigin,
|
||||
|
||||
removeDonateButton: config.removeDonateButton,
|
||||
- httpPort: isValidPort(config.httpPort)? config.httpPort: 3000,
|
||||
+ httpPort: httpPort,
|
||||
httpAddress: typeof(config.httpAddress) === 'string'? config.httpAddress: 'localhost',
|
||||
websocketPath: config.externalWebsocketURL,
|
||||
logIP: config.logIP,
|
||||
--
|
||||
2.45.2
|
||||
|
135
pkgs/by-name/cr/cryptpad/package.nix
Normal file
135
pkgs/by-name/cr/cryptpad/package.nix
Normal file
@ -0,0 +1,135 @@
|
||||
{
|
||||
buildNpmPackage,
|
||||
fetchFromGitHub,
|
||||
lib,
|
||||
makeBinaryWrapper,
|
||||
nixosTests,
|
||||
nodejs,
|
||||
rdfind,
|
||||
}:
|
||||
|
||||
let
|
||||
version = "2024.6.0";
|
||||
# nix version of install-onlyoffice.sh
|
||||
# a later version could rebuild from sdkjs/web-apps as per
|
||||
# https://github.com/cryptpad/onlyoffice-builds/blob/main/build.sh
|
||||
onlyoffice_build =
|
||||
rev: hash:
|
||||
fetchFromGitHub {
|
||||
inherit rev hash;
|
||||
owner = "cryptpad";
|
||||
repo = "onlyoffice-builds";
|
||||
};
|
||||
onlyoffice_install = oo: ''
|
||||
oo_dir="$out_cryptpad/www/common/onlyoffice/dist/${oo.subdir}"
|
||||
cp -a "${onlyoffice_build oo.rev oo.hash}/." "$oo_dir"
|
||||
chmod -R +w "$oo_dir"
|
||||
echo "${oo.rev}" > "$oo_dir/.commit"
|
||||
'';
|
||||
onlyoffice_versions = [
|
||||
{
|
||||
subdir = "v1";
|
||||
rev = "4f370beb";
|
||||
hash = "sha256-TE/99qOx4wT2s0op9wi+SHwqTPYq/H+a9Uus9Zj4iSY=";
|
||||
}
|
||||
{
|
||||
subdir = "v2b";
|
||||
rev = "d9da72fd";
|
||||
hash = "sha256-SiRDRc2vnLwCVnvtk+C8PKw7IeuSzHBaJmZHogRe3hQ=";
|
||||
}
|
||||
{
|
||||
subdir = "v4";
|
||||
rev = "6ebc6938";
|
||||
hash = "sha256-eto1+8Tk/s3kbUCpbUh8qCS8EOq700FYG1/KiHyynaA=";
|
||||
}
|
||||
{
|
||||
subdir = "v5";
|
||||
rev = "88a356f0";
|
||||
hash = "sha256-8j1rlAyHlKx6oAs2pIhjPKcGhJFj6ZzahOcgenyeOCc=";
|
||||
}
|
||||
{
|
||||
subdir = "v6";
|
||||
rev = "abd8a309";
|
||||
hash = "sha256-BZdExj2q/bqUD3k9uluOot2dlrWKA+vpad49EdgXKww=";
|
||||
}
|
||||
{
|
||||
subdir = "v7";
|
||||
rev = "9d8b914a";
|
||||
hash = "sha256-M+rPJ/Xo2olhqB5ViynGRaesMLLfG/1ltUoLnepMPnM=";
|
||||
}
|
||||
];
|
||||
|
||||
in
|
||||
buildNpmPackage {
|
||||
inherit version;
|
||||
pname = "cryptpad";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "cryptpad";
|
||||
repo = "cryptpad";
|
||||
rev = version;
|
||||
hash = "sha256-huIhhnjatkaVfm1zDeqi88EX/nAUBQ0onPNOwn7hrX4=";
|
||||
};
|
||||
|
||||
npmDepsHash = "sha256-Oh1fBvP7OXC+VDiH3D+prHmi8pRrxld06n30sqw5apY=";
|
||||
|
||||
nativeBuildInputs = [
|
||||
makeBinaryWrapper
|
||||
rdfind
|
||||
];
|
||||
|
||||
patches = [
|
||||
# fix httpSafePort setting
|
||||
# https://github.com/cryptpad/cryptpad/pull/1571
|
||||
./0001-env.js-fix-httpSafePort-handling.patch
|
||||
];
|
||||
|
||||
# cryptpad build tries to write in cache dir
|
||||
makeCacheWritable = true;
|
||||
|
||||
# 'npm build run' (scripts/build.js) generates a customize directory, but:
|
||||
# - that is not installed by npm install
|
||||
# - it embeds values from config into the directory, so needs to be
|
||||
# run before starting the server (it's just a few quick replaces)
|
||||
# Skip it here.
|
||||
dontNpmBuild = true;
|
||||
|
||||
postInstall = ''
|
||||
out_cryptpad="$out/lib/node_modules/cryptpad"
|
||||
|
||||
# 'npm run install:components' (scripts/copy-component.js) copies
|
||||
# required node modules to www/component in the build tree...
|
||||
# Move to install directory manually.
|
||||
npm run install:components
|
||||
mv www/components "$out_cryptpad/www/"
|
||||
|
||||
# install OnlyOffice (install-onlyoffice.sh without network)
|
||||
mkdir -p "$out_cryptpad/www/common/onlyoffice/dist"
|
||||
${lib.concatMapStringsSep "\n" onlyoffice_install onlyoffice_versions}
|
||||
rdfind -makehardlinks true -makeresultsfile false "$out_cryptpad/www/common/onlyoffice/dist"
|
||||
|
||||
# cryptpad assumes it runs in the source directory and also outputs
|
||||
# its state files there, which is not exactly great for us.
|
||||
# There are relative paths everywhere so just substituing source paths
|
||||
# is difficult and will likely break on a future update, instead we
|
||||
# make links to the required source directories before running.
|
||||
# The build.js step populates 'customize' from customize.dist and config;
|
||||
# one would normally want to re-run it after modifying config but since it
|
||||
# would overwrite user modifications only run it if there is no customize
|
||||
# directory.
|
||||
makeWrapper "${lib.getExe nodejs}" "$out/bin/cryptpad" \
|
||||
--add-flags "$out_cryptpad/server.js" \
|
||||
--run "for d in customize.dist lib www; do ln -sf \"$out_cryptpad/\$d\" .; done" \
|
||||
--run "if ! [ -d customize ]; then \"${lib.getExe nodejs}\" \"$out_cryptpad/scripts/build.js\"; fi"
|
||||
'';
|
||||
|
||||
passthru.tests.cryptpad = nixosTests.cryptpad;
|
||||
|
||||
meta = {
|
||||
description = "Collaborative office suite, end-to-end encrypted and open-source.";
|
||||
homepage = "https://cryptpad.org/";
|
||||
license = lib.licenses.agpl3Plus;
|
||||
mainProgram = "cryptpad";
|
||||
maintainers = with lib.maintainers; [ martinetd ];
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user