Flytt Caddy fra Docker til native + fiks frontend-kjeden

- Caddy installert via apt, kjører som systemd-service
- Docker-tjenester eksponerer porter på localhost (Authentik:9000,
  Forgejo:3000, SpacetimeDB:9080)
- Caddy-blokk fjernet fra docker-compose.yml
- iptables-hack fjernet (ingen Docker→host-proxy lenger)
- Caddy proxyer /api/* til maskinrommet (unngår CORS)
- SpacetimeDB URL fikset (trailing slash for korrekt URL-resolving)
- Arvet tilgang i nodeVisibility (belongs_to → foreldrenode)
- Signin-side bruker <a> i stedet for client-side signIn()
- /claude redirect-rute for testing
- @auth/core oppgradert 0.34.3→0.41.1

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
vegard 2026-03-17 21:26:06 +00:00
parent ab91e5396d
commit d4715831bf
6 changed files with 49 additions and 111 deletions

View file

@ -83,6 +83,7 @@ for det vi har full kontroll over.
### Native (systemd) ### Native (systemd)
| Tjeneste | Beskrivelse | Deploy | | Tjeneste | Beskrivelse | Deploy |
|----------|-------------|--------| |----------|-------------|--------|
| **Caddy** | Reverse proxy + TLS | `sudo systemctl reload caddy` (config: `/srv/synops/config/caddy/Caddyfile`) |
| **maskinrommet** | Rust API + jobbkø | `cargo build --release``sudo systemctl restart maskinrommet` | | **maskinrommet** | Rust API + jobbkø | `cargo build --release``sudo systemctl restart maskinrommet` |
| **SvelteKit** | Frontend (når klar) | `npm run build` → systemd | | **SvelteKit** | Frontend (når klar) | `npm run build` → systemd |
@ -96,13 +97,14 @@ med Docker container-IPs.
| **PostgreSQL** | Versjonsstyring, enkel oppgradering | | **PostgreSQL** | Versjonsstyring, enkel oppgradering |
| **SpacetimeDB** | Eksperimentelt, offisielt image | | **SpacetimeDB** | Eksperimentelt, offisielt image |
| **Authentik** | Kompleks stack (server + worker + Redis) | | **Authentik** | Kompleks stack (server + worker + Redis) |
| **Caddy** | Enkel TLS-terminering, kan tas native senere |
| **LiteLLM** | Ferdig image, sjelden oppdatering | | **LiteLLM** | Ferdig image, sjelden oppdatering |
| **faster-whisper** | Modellhåndtering, ferdig image | | **faster-whisper** | Modellhåndtering, ferdig image |
### Kommunikasjon mellom lagene ### Kommunikasjon mellom lagene
- Caddy (Docker) → maskinrommet (host): via `host.docker.internal:3100` - Caddy (native) → Docker-tjenester: via localhost-porter
(`extra_hosts: host-gateway` i docker-compose + iptables-regel) (Authentik:9000, Forgejo:3000, SpacetimeDB:9080)
- Caddy (native) → native tjenester: direkte localhost
(maskinrommet:3100, SvelteKit:3200)
- Maskinrommet (host) → Docker-tjenester: via container-IP - Maskinrommet (host) → Docker-tjenester: via container-IP
(løses dynamisk i `maskinrommet-env.sh`) (løses dynamisk i `maskinrommet-env.sh`)

View file

@ -8,7 +8,7 @@
"name": "frontend", "name": "frontend",
"version": "0.0.1", "version": "0.0.1",
"dependencies": { "dependencies": {
"@auth/core": "^0.34.3", "@auth/core": "^0.41.1",
"@auth/sveltekit": "^1.11.1", "@auth/sveltekit": "^1.11.1",
"@tiptap/core": "^3.20.4", "@tiptap/core": "^3.20.4",
"@tiptap/extension-image": "^3.20.4", "@tiptap/extension-image": "^3.20.4",
@ -32,23 +32,21 @@
} }
}, },
"node_modules/@auth/core": { "node_modules/@auth/core": {
"version": "0.34.3", "version": "0.41.1",
"resolved": "https://registry.npmjs.org/@auth/core/-/core-0.34.3.tgz", "resolved": "https://registry.npmjs.org/@auth/core/-/core-0.41.1.tgz",
"integrity": "sha512-jMjY/S0doZnWYNV90x0jmU3B+UcrsfGYnukxYrRbj0CVvGI/MX3JbHsxSrx2d4mbnXaUsqJmAcDfoQWA6r0lOw==", "integrity": "sha512-t9cJ2zNYAdWMacGRMT6+r4xr1uybIdmYa49calBPeTqwgAFPV/88ac9TEvCR85pvATiSPt8VaNf+Gt24JIT/uw==",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@panva/hkdf": "^1.1.1", "@panva/hkdf": "^1.2.1",
"@types/cookie": "0.6.0", "jose": "^6.0.6",
"cookie": "0.6.0", "oauth4webapi": "^3.3.0",
"jose": "^5.1.3", "preact": "10.24.3",
"oauth4webapi": "^2.10.4", "preact-render-to-string": "6.5.11"
"preact": "10.11.3",
"preact-render-to-string": "5.2.3"
}, },
"peerDependencies": { "peerDependencies": {
"@simplewebauthn/browser": "^9.0.1", "@simplewebauthn/browser": "^9.0.1",
"@simplewebauthn/server": "^9.0.2", "@simplewebauthn/server": "^9.0.2",
"nodemailer": "^7" "nodemailer": "^7.0.7"
}, },
"peerDependenciesMeta": { "peerDependenciesMeta": {
"@simplewebauthn/browser": { "@simplewebauthn/browser": {
@ -90,72 +88,6 @@
} }
} }
}, },
"node_modules/@auth/sveltekit/node_modules/@auth/core": {
"version": "0.41.1",
"resolved": "https://registry.npmjs.org/@auth/core/-/core-0.41.1.tgz",
"integrity": "sha512-t9cJ2zNYAdWMacGRMT6+r4xr1uybIdmYa49calBPeTqwgAFPV/88ac9TEvCR85pvATiSPt8VaNf+Gt24JIT/uw==",
"license": "ISC",
"dependencies": {
"@panva/hkdf": "^1.2.1",
"jose": "^6.0.6",
"oauth4webapi": "^3.3.0",
"preact": "10.24.3",
"preact-render-to-string": "6.5.11"
},
"peerDependencies": {
"@simplewebauthn/browser": "^9.0.1",
"@simplewebauthn/server": "^9.0.2",
"nodemailer": "^7.0.7"
},
"peerDependenciesMeta": {
"@simplewebauthn/browser": {
"optional": true
},
"@simplewebauthn/server": {
"optional": true
},
"nodemailer": {
"optional": true
}
}
},
"node_modules/@auth/sveltekit/node_modules/jose": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/jose/-/jose-6.2.1.tgz",
"integrity": "sha512-jUaKr1yrbfaImV7R2TN/b3IcZzsw38/chqMpo2XJ7i2F8AfM/lA4G1goC3JVEwg0H7UldTmSt3P68nt31W7/mw==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/panva"
}
},
"node_modules/@auth/sveltekit/node_modules/oauth4webapi": {
"version": "3.8.5",
"resolved": "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-3.8.5.tgz",
"integrity": "sha512-A8jmyUckVhRJj5lspguklcl90Ydqk61H3dcU0oLhH3Yv13KpAliKTt5hknpGGPZSSfOwGyraNEFmofDYH+1kSg==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/panva"
}
},
"node_modules/@auth/sveltekit/node_modules/preact": {
"version": "10.24.3",
"resolved": "https://registry.npmjs.org/preact/-/preact-10.24.3.tgz",
"integrity": "sha512-Z2dPnBnMUfyQfSQ+GBdsGa16hz35YmLmtTLhM169uW944hYL6xzTYkJjC07j+Wosz733pMWx0fgON3JNw1jJQA==",
"license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/preact"
}
},
"node_modules/@auth/sveltekit/node_modules/preact-render-to-string": {
"version": "6.5.11",
"resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-6.5.11.tgz",
"integrity": "sha512-ubnauqoGczeGISiOh6RjX0/cdaF8v/oDXIjO85XALCQjwQP+SB4RDXXtvZ6yTYSjG+PC1QRP2AhPgCEsM2EvUw==",
"license": "MIT",
"peerDependencies": {
"preact": ">=10"
}
},
"node_modules/@auth/sveltekit/node_modules/set-cookie-parser": { "node_modules/@auth/sveltekit/node_modules/set-cookie-parser": {
"version": "2.7.2", "version": "2.7.2",
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz",
@ -2255,9 +2187,9 @@
} }
}, },
"node_modules/jose": { "node_modules/jose": {
"version": "5.10.0", "version": "6.2.1",
"resolved": "https://registry.npmjs.org/jose/-/jose-5.10.0.tgz", "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.1.tgz",
"integrity": "sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==", "integrity": "sha512-jUaKr1yrbfaImV7R2TN/b3IcZzsw38/chqMpo2XJ7i2F8AfM/lA4G1goC3JVEwg0H7UldTmSt3P68nt31W7/mw==",
"license": "MIT", "license": "MIT",
"funding": { "funding": {
"url": "https://github.com/sponsors/panva" "url": "https://github.com/sponsors/panva"
@ -2613,9 +2545,9 @@
} }
}, },
"node_modules/oauth4webapi": { "node_modules/oauth4webapi": {
"version": "2.17.0", "version": "3.8.5",
"resolved": "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-2.17.0.tgz", "resolved": "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-3.8.5.tgz",
"integrity": "sha512-lbC0Z7uzAFNFyzEYRIC+pkSVvDHJTbEW+dYlSBAlCYDe6RxUkJ26bClhk8ocBZip1wfI9uKTe0fm4Ib4RHn6uQ==", "integrity": "sha512-A8jmyUckVhRJj5lspguklcl90Ydqk61H3dcU0oLhH3Yv13KpAliKTt5hknpGGPZSSfOwGyraNEFmofDYH+1kSg==",
"license": "MIT", "license": "MIT",
"funding": { "funding": {
"url": "https://github.com/sponsors/panva" "url": "https://github.com/sponsors/panva"
@ -2703,9 +2635,9 @@
} }
}, },
"node_modules/preact": { "node_modules/preact": {
"version": "10.11.3", "version": "10.24.3",
"resolved": "https://registry.npmjs.org/preact/-/preact-10.11.3.tgz", "resolved": "https://registry.npmjs.org/preact/-/preact-10.24.3.tgz",
"integrity": "sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==", "integrity": "sha512-Z2dPnBnMUfyQfSQ+GBdsGa16hz35YmLmtTLhM169uW944hYL6xzTYkJjC07j+Wosz733pMWx0fgON3JNw1jJQA==",
"license": "MIT", "license": "MIT",
"funding": { "funding": {
"type": "opencollective", "type": "opencollective",
@ -2713,13 +2645,10 @@
} }
}, },
"node_modules/preact-render-to-string": { "node_modules/preact-render-to-string": {
"version": "5.2.3", "version": "6.5.11",
"resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.3.tgz", "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-6.5.11.tgz",
"integrity": "sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA==", "integrity": "sha512-ubnauqoGczeGISiOh6RjX0/cdaF8v/oDXIjO85XALCQjwQP+SB4RDXXtvZ6yTYSjG+PC1QRP2AhPgCEsM2EvUw==",
"license": "MIT", "license": "MIT",
"dependencies": {
"pretty-format": "^3.8.0"
},
"peerDependencies": { "peerDependencies": {
"preact": ">=10" "preact": ">=10"
} }
@ -2739,12 +2668,6 @@
"url": "https://github.com/prettier/prettier?sponsor=1" "url": "https://github.com/prettier/prettier?sponsor=1"
} }
}, },
"node_modules/pretty-format": {
"version": "3.8.0",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz",
"integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==",
"license": "MIT"
},
"node_modules/prosemirror-changeset": { "node_modules/prosemirror-changeset": {
"version": "2.4.0", "version": "2.4.0",
"resolved": "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.4.0.tgz", "resolved": "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.4.0.tgz",

View file

@ -23,7 +23,7 @@
"vite": "^7.3.1" "vite": "^7.3.1"
}, },
"dependencies": { "dependencies": {
"@auth/core": "^0.34.3", "@auth/core": "^0.41.1",
"@auth/sveltekit": "^1.11.1", "@auth/sveltekit": "^1.11.1",
"@tiptap/core": "^3.20.4", "@tiptap/core": "^3.20.4",
"@tiptap/extension-image": "^3.20.4", "@tiptap/extension-image": "^3.20.4",

View file

@ -301,6 +301,17 @@ export function nodeVisibility(
// Explicit access via node_access // Explicit access via node_access
if (nodeAccessStore.hasAccess(userId, node.id)) return 'full'; if (nodeAccessStore.hasAccess(userId, node.id)) return 'full';
// Inherited access: if this node belongs_to a node the user has access to
// (e.g. messages in a communication node)
for (const edge of edgeStore.bySource(node.id)) {
if (edge.edgeType === 'belongs_to') {
const parent = nodeStore.get(edge.targetId);
if (parent && (parent.createdBy === userId || nodeAccessStore.hasAccess(userId, parent.id))) {
return 'full';
}
}
}
// Public visibility // Public visibility
if (node.visibility === 'readable' || node.visibility === 'open') return 'full'; if (node.visibility === 'readable' || node.visibility === 'open') return 'full';
if (node.visibility === 'discoverable') return 'discoverable'; if (node.visibility === 'discoverable') return 'discoverable';

View file

@ -0,0 +1,6 @@
import { redirect } from '@sveltejs/kit';
import type { PageServerLoad } from './$types';
export const load: PageServerLoad = async () => {
redirect(302, '/chat/e4eebc99-9c0b-4ef8-bb6d-6bb9bd380a55');
};

View file

@ -1,18 +1,14 @@
<script lang="ts">
import { signIn } from '@auth/sveltekit/client';
</script>
<div class="flex min-h-screen items-center justify-center bg-gray-50"> <div class="flex min-h-screen items-center justify-center bg-gray-50">
<div class="w-full max-w-sm space-y-6 text-center"> <div class="w-full max-w-sm space-y-6 text-center">
<div> <div>
<h1 class="text-4xl font-bold text-gray-900">Synops</h1> <h1 class="text-4xl font-bold text-gray-900">Synops</h1>
<p class="mt-2 text-gray-600">Logg inn for å fortsette</p> <p class="mt-2 text-gray-600">Logg inn for å fortsette</p>
</div> </div>
<button <a
onclick={() => signIn('authentik')} href="/auth/signin/authentik"
class="w-full rounded-lg bg-gray-900 px-4 py-3 text-sm font-medium text-white hover:bg-gray-800 focus:ring-2 focus:ring-gray-900 focus:ring-offset-2 focus:outline-none" class="block w-full rounded-lg bg-gray-900 px-4 py-3 text-sm font-medium text-white hover:bg-gray-800 focus:ring-2 focus:ring-gray-900 focus:ring-offset-2 focus:outline-none"
> >
Logg inn med Authentik Logg inn med Authentik
</button> </a>
</div> </div>
</div> </div>