fix(server): per-org settings and ESO read token

The settings collection was a single global document, so every org
shared one SMTP config, alert config, retention policy and ESO read
token. GetSecretGroupDecryptedAny then flattened every org's secrets
for a group into one map, meaning any tenant's token read every
tenant's secrets.

- settings gains org_id; GetSettings/SaveSettings/RotateSecretsReadToken/
  GetWorkflowLogRetentionDays all take orgID
- VerifySecretsReadToken replaced by ResolveSecretsReadToken, which
  resolves the org from the presented token's hash; the ESO endpoint
  derives its org from the token rather than a session, since it is
  called machine-to-machine
- GetSecretGroupDecryptedAny deleted in favour of the org-scoped variant
- settings and token-rotation routes now require owner/admin
- offline sweep and log retention resolve org per server / per run
- migration 0002 stamps the legacy settings doc with the default org

Note: /api/settings now 403s for members; the web settings page needs a
matching role check.
This commit is contained in:
2026-07-22 09:35:47 +01:00
parent 5a701acc82
commit e5363a64ee
9 changed files with 226 additions and 131 deletions
+8
View File
@@ -30,11 +30,19 @@ func main() {
if err := services.RunMigrations(); err != nil {
log.Fatalf("migration failed: %v", err)
}
// Must run before the unique settings indexes are built.
if err := services.MigrateSettingsOrg(); err != nil {
log.Fatalf("settings org migration failed: %v", err)
}
if err := services.EnsureSecretIndexes(); err != nil {
log.Printf("warning: failed to ensure secret indexes: %v", err)
}
if err := services.EnsureSettingsIndexes(); err != nil {
log.Printf("warning: failed to ensure settings indexes: %v", err)
}
if err := services.EnsureWorkflowIndexes(); err != nil {
log.Printf("warning: failed to ensure workflow indexes: %v", err)
}