- ChatBubble: useActionSheet replaces custom Modal (native iOS popup, Android bottom sheet) - DM mode (isDM prop): hides like-count, shows Insta-style heart badge under bubble when liked - Group chat unchanged - Cleanup: remove unused Modal/Platform imports, sheet styles, actionsOpen state - deploy.sh: auto-detect ANDROID_HOME + auto-create local.properties for local Gradle - NEXT_RELEASE.md: DM reactions release note - Includes other staged work across binder-mac, marketing, ops/mdm, ios/
112 lines
4.5 KiB
Plaintext
112 lines
4.5 KiB
Plaintext
# ReBreak Unsupervised Sideload Profile — nginx Distribution Snippet
|
|
# ===================================================================
|
|
# Einbinden in den bestehenden mdm.rebreak.org / app.rebreak.org server-block.
|
|
# Pre-generierte per-User-Profiles liegen unter /srv/rebreak/profiles/users/
|
|
# Layout: /srv/rebreak/profiles/users/<user_id>.mobileconfig
|
|
|
|
# Variante A: per-User-Token-gated Distribution (RECOMMENDED für Production)
|
|
# ---------------------------------------------------------------------------
|
|
# Backend signiert einen kurzlebigen Download-Token (JWT) und der User klickt
|
|
# einen Link wie:
|
|
# https://app.rebreak.org/profile/download?t=eyJhbGc...
|
|
# nginx ruft das Backend (auth_request) auf um zu validieren bevor er das
|
|
# Profile ausliefert. Profile selbst sind unsigned, aber der Zugriff ist
|
|
# geschützt — verhindert dass Profiles auf öffentlichen URLs leaken.
|
|
|
|
location = /profile/download {
|
|
# JWT-Validation gegen Backend (Backend returnt 200 + X-User-Id Header)
|
|
auth_request /auth/validate-profile-token;
|
|
auth_request_set $user_id $upstream_http_x_user_id;
|
|
|
|
# Internal-only Redirect zum echten Profile-File
|
|
error_page 200 = @serve_profile;
|
|
return 200;
|
|
}
|
|
|
|
location @serve_profile {
|
|
internal;
|
|
alias /srv/rebreak/profiles/users/$user_id.mobileconfig;
|
|
|
|
# iOS-spezifischer Content-Type — Apple Aspen Profile
|
|
# https://developer.apple.com/library/archive/featuredarticles/iPhoneConfigurationProfileRef/
|
|
default_type application/x-apple-aspen-config;
|
|
|
|
# Forciert Download-Dialog statt Inline-Display in Safari → triggert
|
|
# iOS-Profile-Install-Flow ab iOS 12.2 (Safari öffnet Settings.app).
|
|
add_header Content-Disposition 'attachment; filename="ReBreak-Schutz.mobileconfig"';
|
|
|
|
# Strict Security-Headers
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
add_header Cache-Control "no-store, no-cache, must-revalidate" always;
|
|
|
|
# HTTPS-Only — HSTS preload-ready
|
|
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
|
}
|
|
|
|
location = /auth/validate-profile-token {
|
|
internal;
|
|
proxy_pass http://127.0.0.1:3000/api/profile/validate-token;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Forwarded-For $remote_addr;
|
|
proxy_set_header X-Original-URI $request_uri;
|
|
# Token kommt als Query-Param, Backend liest's selber raus
|
|
}
|
|
|
|
|
|
# Variante B: static-served für interne Tests (NICHT Production)
|
|
# ---------------------------------------------------------------------------
|
|
# Eine generische .mobileconfig für Dev-Tests. Token-Auth weglassen — die URL
|
|
# ist die Auth (security through obscurity, nur für interne Tester teilen).
|
|
|
|
location = /dev/rebreak-schutz-test.mobileconfig {
|
|
alias /srv/rebreak/profiles/dev/rebreak-iphone-unsupervised-sideload.mobileconfig;
|
|
default_type application/x-apple-aspen-config;
|
|
add_header Content-Disposition 'attachment; filename="ReBreak-Schutz-DEV.mobileconfig"';
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
add_header Cache-Control "no-store" always;
|
|
|
|
# IP-Whitelist für interne Tester (Beispiel — anpassen oder weglassen)
|
|
# allow 49.13.55.22; # rebreak-server
|
|
# allow 178.105.101.137; # rebreak-mdm
|
|
# deny all;
|
|
}
|
|
|
|
|
|
# HTTPS-Enforcement (sollte global in main server-block sein, hier zur
|
|
# Vollständigkeit — falls noch nicht gesetzt)
|
|
# ---------------------------------------------------------------------------
|
|
# iOS akzeptiert .mobileconfig-Download nur über HTTPS. HTTP-Versuche werden
|
|
# entweder geredirected oder vom System silent verworfen.
|
|
|
|
# server {
|
|
# listen 80;
|
|
# server_name app.rebreak.org;
|
|
# return 301 https://$host$request_uri;
|
|
# }
|
|
|
|
|
|
# Deploy-Hinweise
|
|
# ---------------------------------------------------------------------------
|
|
# 1. Generator-Run auf rebreak-server:
|
|
# cd /srv/rebreak/ops/mdm/profiles
|
|
# python3 generate-unsupervised-profile.py \
|
|
# --batch /srv/rebreak/data/users-pending.csv \
|
|
# --output-dir /srv/rebreak/profiles/users/ \
|
|
# --org "ReBreak GmbH"
|
|
#
|
|
# 2. Permissions:
|
|
# chown -R www-data:www-data /srv/rebreak/profiles/
|
|
# chmod 750 /srv/rebreak/profiles/
|
|
# chmod 640 /srv/rebreak/profiles/users/*.mobileconfig
|
|
#
|
|
# 3. nginx reload:
|
|
# nginx -t && systemctl reload nginx
|
|
#
|
|
# 4. Verify-Curl (sollte 401 ohne Token zurückgeben):
|
|
# curl -I https://app.rebreak.org/profile/download
|
|
#
|
|
# 5. Verify Content-Type mit echtem Token:
|
|
# curl -I -H "Authorization: Bearer $TOKEN" \
|
|
# "https://app.rebreak.org/profile/download?t=$TOKEN"
|
|
# Erwartet: Content-Type: application/x-apple-aspen-config
|