3 Commits

Author SHA1 Message Date
Lennart J. Kurzweg (Nx2)
65aeeda263 Merge branch 'master' of ssh://ssh.nx2.site:50022/nx2/nxcaldav 2026-04-23 17:32:33 +02:00
Lennart J. Kurzweg (Nx2)
f61e014d2a smtp pw 2026-04-23 17:32:30 +02:00
ce6a5c7477 Delete shell.nix 2026-04-23 17:21:10 +02:00
6 changed files with 46 additions and 73 deletions

View File

@@ -3,74 +3,45 @@ database:
server: server:
bind_address: 0.0.0.0:14243 bind_address: 0.0.0.0:14243
default_class: CONFIDENTIAL default_class: CONFIDENTIAL
public_url: http://nxc.nx2.site/ public_url: http://example.com/
email_domain: nx2.site email_domain: example.com
redaction_text: '[-]' redaction_text: '[-]'
smtp: smtp:
host: localhost host: localhost
port: 587 port: 587
user: nxcaldav@nx2.site user: nxcaldav@nx2.site
password: Vastly-Wrinkle9-Corsage password_cmd: echo "Vastly-Wrinkle9-Corsage"
users: users:
- name: daniel - name: alice
password: ll password: 123
groups: groups:
- family - family
- name: lennart - name: bob
password: ll password: abc
groups: groups:
- family - family
- name: shared
password: Oxidant-Ageless3-Dispersed
calendars: calendars:
- id: preservation - id: test
owner: lennart owner: alice
color: '#F6F5F4' color: '#F6F5F4'
- id: effort - id: family
owner: lennart
color: '#FF0000'
- id: experience
owner: lennart
color: '#2C33FF'
- id: leisure
owner: lennart
color: '#10B400'
- id: daniel
owner: daniel
color: '#ff2222'
- access:
- group: family
mode: read-write
id: family
owner: shared owner: shared
color: '#999999' color: '#999999'
access:
- group: family
mode: read-write
address_books: address_books:
- id: contacts - id: contacts
owner: lennart owner: alice
- id: contacts
owner: daniel
- id: family - id: family
owner: shared owner: bob
access: access:
- group: family - group: family
mode: read-write mode: read-write
aggregates: aggregates:
- access:
- group: family
mode: read-only
- ics: future-only
id: lennart-aggregat
owner: lennart
color: '#dd9999'
sources:
- preservation
- effort
- experience
- leisure
- family

View File

@@ -8,7 +8,6 @@ import (
"log" "log"
"net/http" "net/http"
"net/url" "net/url"
"os/exec"
"path" "path"
"slices" "slices"
"strings" "strings"
@@ -140,16 +139,9 @@ func (b *DBBackend) initSchema(ctx context.Context) error {
} }
func (b *DBBackend) resolvePassword(u config.User) (string, error) { func (b *DBBackend) resolvePassword(u config.User) (string, error) {
var raw string raw, err := config.ResolvePassword(u.Password, u.PasswordCmd)
if u.PasswordCmd != "" { if err != nil {
cmd := exec.Command("sh", "-c", u.PasswordCmd) return "", fmt.Errorf("failed to resolve password for %s: %v", u.Name, err)
out, err := cmd.Output()
if err != nil {
return "", fmt.Errorf("failed to run password command for %s: %v", u.Name, err)
}
raw = strings.TrimSpace(string(out))
} else {
raw = u.Password
} }
// If it already looks like a bcrypt hash, return as is. // If it already looks like a bcrypt hash, return as is.

View File

@@ -10,6 +10,7 @@ import (
"strings" "strings"
"github.com/emersion/go-ical" "github.com/emersion/go-ical"
"nxcaldav/internal/config"
) )
// sendInvitation sends an iMIP (RFC 6047) invitation email. // sendInvitation sends an iMIP (RFC 6047) invitation email.
@@ -99,8 +100,14 @@ func (b *DBBackend) sendInvitation(senderName, recipientEmail, summary, descript
if err = c.StartTLS(tlsConfig); err != nil { return err } if err = c.StartTLS(tlsConfig); err != nil { return err }
} }
} }
if b.smtp.User != "" && b.smtp.Password != "" {
auth := smtp.PlainAuth("", b.smtp.User, b.smtp.Password, b.smtp.Host) smtpPassword, err := config.ResolvePassword(b.smtp.Password, b.smtp.PasswordCmd)
if err != nil {
return fmt.Errorf("failed to resolve SMTP password: %v", err)
}
if b.smtp.User != "" && smtpPassword != "" {
auth := smtp.PlainAuth("", b.smtp.User, smtpPassword, b.smtp.Host)
if err = c.Auth(auth); err != nil { return err } if err = c.Auth(auth); err != nil { return err }
} }

View File

@@ -1,8 +1,10 @@
package config package config
import ( import (
"fmt"
"net/url" "net/url"
"os" "os"
"os/exec"
"slices" "slices"
"strings" "strings"
@@ -64,10 +66,11 @@ func (s ServerConfig) BasePath() string {
type SMTPConfig struct { type SMTPConfig struct {
Host string `yaml:"host"` Host string `yaml:"host"`
Port int `yaml:"port"` Port int `yaml:"port"`
User string `yaml:"user"` User string `yaml:"user"`
Password string `yaml:"password"` Password string `yaml:"password"`
PasswordCmd string `yaml:"password_cmd"`
} }
type Config struct { type Config struct {
@@ -79,6 +82,18 @@ type Config struct {
AddressBooks []AddressBook `yaml:"address_books"` AddressBooks []AddressBook `yaml:"address_books"`
Aggregates []Aggregate `yaml:"aggregates"` Aggregates []Aggregate `yaml:"aggregates"`
} }
func ResolvePassword(password, passwordCmd string) (string, error) {
if passwordCmd != "" {
cmd := exec.Command("sh", "-c", passwordCmd)
out, err := cmd.Output()
if err != nil {
return "", fmt.Errorf("failed to run password command: %v", err)
}
return strings.TrimSpace(string(out)), nil
}
return password, nil
}
func (c *Config) setDefaults() { func (c *Config) setDefaults() {
if c.Server.BindAddress == "" { c.Server.BindAddress = ":8080" } if c.Server.BindAddress == "" { c.Server.BindAddress = ":8080" }
if c.Server.Redaction == "" { c.Server.Redaction = "Busy" } if c.Server.Redaction == "" { c.Server.Redaction = "Busy" }

BIN
main

Binary file not shown.

View File

@@ -1,12 +0,0 @@
{ pkgs ? import <nixpkgs> { } }: let
my-python = pkgs.python312;
python-with-my-packages = my-python.withPackages (p: with p; [
ical
ics
caldav
pyyaml
psycopg2
]);
in pkgs.mkShell {
buildInputs = [ python-with-my-packages ];
}