Files
calendars/bin/scalingo_postfrontend
Sylvain Zimmer 9c18f96090 (all) add organizations, resources, channels, and infra migration (#34)
Add multi-tenant organization model populated from OIDC claims with
org-scoped user discovery, CalDAV principal filtering, and cross-org
isolation at the SabreDAV layer.

Add bookable resource principals (rooms, equipment) with CalDAV
auto-scheduling that handles conflict detection, auto-accept/decline,
and org-scoped booking enforcement. Fixes #14.

Replace CalendarSubscriptionToken with a unified Channel model
supporting CalDAV integration tokens and iCal feed URLs, with
encrypted token storage and role-based access control. Fixes #16.

Migrate task queue from Celery to Dramatiq with async ICS import,
progress tracking, and task status polling endpoint.

Replace nginx with Caddy for both the reverse proxy and frontend
static serving. Switch frontend package manager from yarn/pnpm to
npm and upgrade Node to 24, Next.js to 16, TypeScript to 5.9.

Harden security with fail-closed entitlements, RSVP rate limiting
and token expiry, CalDAV proxy path validation blocking internal
API routes, channel path scope enforcement, and ETag-based
conflict prevention.

Add frontend pages for resource management and integration channel
CRUD, with resource booking in the event modal.

Restructure CalDAV paths to /calendars/users/ and
/calendars/resources/ with nested principal collections in SabreDAV.
2026-03-09 09:09:34 +01:00

121 lines
5.3 KiB
Bash

#!/bin/bash
set -o errexit # always exit on error
set -o pipefail # don't ignore exit codes when piping output
echo "-----> Running post-frontend script"
# Move the frontend build to the app root and clean up
mkdir -p build/
mv src/frontend/apps/calendars/out build/frontend-out
cp src/frontend/apps/calendars/src/features/i18n/translations.json translations.json
mv src/backend/* ./
# Download Caddy binary with checksum verification
CADDY_VERSION="2.11.2"
CADDY_SHA256="94391dfefe1f278ac8f387ab86162f0e88d87ff97df367f360e51e3cda3df56f"
CADDY_TAR="/tmp/caddy.tar.gz"
curl -fsSL -o "$CADDY_TAR" \
"https://github.com/caddyserver/caddy/releases/download/v${CADDY_VERSION}/caddy_${CADDY_VERSION}_linux_amd64.tar.gz"
echo "${CADDY_SHA256} ${CADDY_TAR}" | sha256sum -c -
tar -xz -C bin/ caddy < "$CADDY_TAR"
rm "$CADDY_TAR"
chmod +x bin/caddy
# Copy Caddyfile (uses {$ENV} vars natively, no ERB needed)
cp src/proxy/Caddyfile ./Caddyfile
echo "3.13" > .python-version
# --- PHP + SabreDAV setup ---
echo "-----> Installing PHP 8.3 from Ubuntu packages"
PHP_PREFIX=".php"
DEB_DIR="/tmp/php-debs"
mkdir -p "$DEB_DIR" "$PHP_PREFIX"
# Hardcoded Launchpad URLs for PHP 8.3.6-0maysync1 (Ubuntu Noble amd64)
# Source: https://launchpad.net/ubuntu/noble/amd64/php8.3-fpm/8.3.6-0maysync1
# Format: "package_name url sha256"
PHP_DEBS=(
"php8.3-cli http://launchpadlibrarian.net/724872605/php8.3-cli_8.3.6-0maysync1_amd64.deb 8cb7461dd06fb214b30c060b80b1c6f95d1ff5e2656fdadf215e50b9f299f196"
"php8.3-fpm http://launchpadlibrarian.net/724872610/php8.3-fpm_8.3.6-0maysync1_amd64.deb b3a9435025766bcbf6c16199c06481c5196098c084933dfabf8867c982edc2b2"
"php8.3-common http://launchpadlibrarian.net/724872606/php8.3-common_8.3.6-0maysync1_amd64.deb 0e0d0ad9c17add5fb2afcc14c6fffb81c2beb99114108b8ebd0461d910a79dfc"
"php8.3-opcache http://launchpadlibrarian.net/724872623/php8.3-opcache_8.3.6-0maysync1_amd64.deb 13b2662201c57904c1eda9b048b1349acaf3609c7d9e8df5b2d93833a059bdb0"
"php8.3-readline http://launchpadlibrarian.net/724872627/php8.3-readline_8.3.6-0maysync1_amd64.deb 380f8ed79196914ee2eebb68bf518a752204826af1fdb8a0d5c9609c76086b90"
"php8.3-pgsql http://launchpadlibrarian.net/724872624/php8.3-pgsql_8.3.6-0maysync1_amd64.deb b1ed204c980c348d1870cfa88c1b40257621ae5696a2a7f44f861a9d00eb7477"
"php8.3-xml http://launchpadlibrarian.net/724872633/php8.3-xml_8.3.6-0maysync1_amd64.deb 6c6ded219d1966a50108d032b7a522e641765a8a6aa48747483313fa7dafd533"
"php8.3-mbstring http://launchpadlibrarian.net/724872617/php8.3-mbstring_8.3.6-0maysync1_amd64.deb 42c89945eb105c2232ab208b893ef65e9abc8af5c95aa10c507498655ef812c4"
"php8.3-curl http://launchpadlibrarian.net/724872607/php8.3-curl_8.3.6-0maysync1_amd64.deb 95d46a22e6b493ba0b6256cf036a2a37d4b9b5f438968073709845af1c17df4c"
"php-common http://launchpadlibrarian.net/710804987/php-common_93ubuntu2_all.deb 39b15c407700e81ddd62580736feba31b187ffff56f6835dac5fa8f847c42529"
)
for entry in "${PHP_DEBS[@]}"; do
read -r pkg url sha256 <<< "$entry"
echo " Downloading ${pkg}"
curl -fsSL -o "$DEB_DIR/${pkg}.deb" "$url"
echo "${sha256} ${DEB_DIR}/${pkg}.deb" | sha256sum -c -
done
for deb in "$DEB_DIR"/*.deb; do
dpkg-deb -x "$deb" "$PHP_PREFIX"
done
# Detect PHP extension directory (e.g. .php/usr/lib/php/20230831)
EXT_DIR_NAME="$(ls -1 "$PHP_PREFIX/usr/lib/php/" | grep '^20' | head -1)"
echo " Extension API dir: ${EXT_DIR_NAME}"
echo " Available .so files: $(ls "$PHP_PREFIX/usr/lib/php/$EXT_DIR_NAME/" 2>/dev/null | tr '\n' ' ')"
# Build a single php.ini that sets extension_dir (relative to /app at runtime)
# then loads every shared extension present.
# Conf.d symlinks from debs are broken (absolute paths to /etc/php/...),
# so we bypass them entirely with a self-contained ini.
PHP_INI="$PHP_PREFIX/php.ini"
{
echo "; Auto-generated PHP config"
echo "extension_dir = /app/.php/usr/lib/php/${EXT_DIR_NAME}"
echo ""
for so in "$PHP_PREFIX/usr/lib/php/$EXT_DIR_NAME"/*.so; do
[ -f "$so" ] || continue
name="$(basename "$so")"
if [ "$name" = "opcache.so" ]; then
echo "zend_extension = ${name}"
else
echo "extension = ${name}"
fi
done
} > "$PHP_INI"
echo " Generated php.ini:"
cat "$PHP_INI" | sed 's/^/ /'
# Create a build-time copy with the current path (not /app)
BUILD_INI="/tmp/php-build.ini"
sed "s|/app/.php|$PWD/.php|" "$PHP_INI" > "$BUILD_INI"
# Create php wrapper (uses /app php.ini at runtime)
cat > bin/php << 'WRAPPER'
#!/bin/bash
DIR="$(cd "$(dirname "$0")/.." && pwd)"
exec "$DIR/.php/usr/bin/php8.3" -c "$DIR/.php/php.ini" -n "$@"
WRAPPER
chmod +x bin/php
# For build-time, verify with the build-time ini
echo "-----> PHP version: $("$PHP_PREFIX/usr/bin/php8.3" -n -c "$BUILD_INI" -v | head -1)"
echo "-----> PHP modules: $("$PHP_PREFIX/usr/bin/php8.3" -n -c "$BUILD_INI" -m | tr '\n' ' ')"
# Download Composer with integrity verification and install SabreDAV dependencies
echo "-----> Installing SabreDAV dependencies"
COMPOSER_VERSION="2.9.5"
COMPOSER_SHA256="c86ce603fe836bf0861a38c93ac566c8f1e69ac44b2445d9b7a6a17ea2e9972a"
curl -fsSL -o bin/composer.phar \
"https://getcomposer.org/download/${COMPOSER_VERSION}/composer.phar"
echo "${COMPOSER_SHA256} bin/composer.phar" | sha256sum -c -
cp -r src/caldav sabredav
cd sabredav
"../$PHP_PREFIX/usr/bin/php8.3" -n -c "$BUILD_INI" ../bin/composer.phar install \
--no-dev --optimize-autoloader --no-interaction
cd ..