Adds a "Via AnyDrop" flow for senders who need to reach someone not present on the mesh. The file is sealed client-side (XChaCha20-Poly1305), uploaded directly to an in-cluster MinIO bucket via a presigned PUT, and handed off to the recipient as a URL whose fragment carries the key. The server only ever sees ciphertext, opaque metadata blobs, and sizes. - server: transfers table (drizzle migration), /api/transfers CRUD + consume endpoint, presigned PUT/GET via @aws-sdk/client-s3, cleanup loop that purges expired + exhausted blobs. - web: @noble/ciphers sealFile/openFile, high-level sendCloud/receive helpers, CloudSharePanel on Home, /r/:id receive page, /inbox page for signed-in users (sent + received tabs). - k8s: MinIO StatefulSet with bucket-init initContainer, S3 env vars on the server Deployment (credentials pulled from minio-credentials Secret). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
108 lines
3.0 KiB
YAML
108 lines
3.0 KiB
YAML
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: anydrop-server-config
|
|
namespace: anydrop
|
|
data:
|
|
PORT: "3001"
|
|
BASE_URL: "https://anydrop.arthurbarre.fr"
|
|
APP_URL: "https://anydrop.arthurbarre.fr"
|
|
VAPID_PUBLIC_KEY: "BCta0SNLmjBFfizMInnBhEQvVZlMbbaM-qw1a-p3JeQykCyy00GRGkDAKMDA5nv5UfokwJ30HRGoA6buJjWwKcE"
|
|
VAPID_PRIVATE_KEY: "gbmrcm9Tuz4JgoHophO-jUbam8rV9YgjImYcWvoE0w0"
|
|
VAPID_SUBJECT: "mailto:arthurbarre.js@gmail.com"
|
|
SMTP_HOST: "maddy.anydrop.svc.cluster.local"
|
|
SMTP_PORT: "587"
|
|
SMTP_SECURE: "false"
|
|
SMTP_TLS_REJECT_UNAUTHORIZED: "false"
|
|
SMTP_FROM: "AnyDrop <noreply@anydrop.arthurbarre.fr>"
|
|
# Phase 2 — encrypted cloud relay (MinIO in-cluster)
|
|
# Endpoint must be publicly reachable: the browser uses presigned URLs
|
|
# signed against this host, so the hostname seen by the server and the
|
|
# client must match. Ingress routes s3.anydrop.arthurbarre.fr → minio:9000.
|
|
S3_ENDPOINT: "https://s3.anydrop.arthurbarre.fr"
|
|
S3_REGION: "us-east-1"
|
|
S3_BUCKET: "transfers"
|
|
S3_FORCE_PATH_STYLE: "true"
|
|
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: anydrop-server
|
|
namespace: anydrop
|
|
spec:
|
|
replicas: 1
|
|
selector:
|
|
matchLabels:
|
|
app: anydrop-server
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: anydrop-server
|
|
spec:
|
|
initContainers:
|
|
- name: db-migrate
|
|
image: git.arthurbarre.fr/ordinarthur/anydrop-server:latest
|
|
command: ["node", "server/dist/db/migrate.js"]
|
|
envFrom:
|
|
- configMapRef:
|
|
name: anydrop-server-config
|
|
- secretRef:
|
|
name: anydrop-app-secrets
|
|
containers:
|
|
- name: anydrop-server
|
|
image: git.arthurbarre.fr/ordinarthur/anydrop-server:latest
|
|
ports:
|
|
- containerPort: 3001
|
|
envFrom:
|
|
- configMapRef:
|
|
name: anydrop-server-config
|
|
- secretRef:
|
|
name: anydrop-app-secrets
|
|
env:
|
|
- name: S3_ACCESS_KEY
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: minio-credentials
|
|
key: access_key
|
|
- name: S3_SECRET_KEY
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: minio-credentials
|
|
key: secret_key
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /health
|
|
port: 3001
|
|
initialDelaySeconds: 10
|
|
periodSeconds: 30
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /health
|
|
port: 3001
|
|
initialDelaySeconds: 5
|
|
periodSeconds: 10
|
|
resources:
|
|
requests:
|
|
memory: "96Mi"
|
|
cpu: "50m"
|
|
limits:
|
|
memory: "192Mi"
|
|
cpu: "300m"
|
|
imagePullSecrets:
|
|
- name: gitea-registry
|
|
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: anydrop-server
|
|
namespace: anydrop
|
|
spec:
|
|
type: ClusterIP
|
|
selector:
|
|
app: anydrop-server
|
|
ports:
|
|
- port: 3001
|
|
targetPort: 3001
|