#!/bin/bash
#
# Plane Service

PATH=$HOME/.docker/cli-plugins:/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

. /federated/lib/helpers.sh

# FIXME plane's nginx proxy has a few additional rules that we may
# need to port to Traefik:
#        add_header X-Content-Type-Options    "nosniff" always;
#        add_header Referrer-Policy           "no-referrer-when-downgrade" always;
#        add_header Permissions-Policy        "interest-cohort=()" always;
#        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
#        add_header X-Forwarded-Proto         "$scheme";
#        add_header X-Forwarded-Host          "$host";
#        add_header X-Forwarded-For           "$proxy_add_x_forwarded_for";
#        add_header X-Real-IP                 "$remote_addr";

config_plane() {
	echo -ne "\n* Configuring /federated/apps/plane container.."

	if [ ! -d "/federated/apps/plane" ]; then
		mkdir -p /federated/apps/plane/data/plane &> /dev/null
	fi

	POSTGRES_PASSWORD=$(create_password)
	EMAIL_PASSWORD="$(cat /federated/apps/panel/.env |grep ^SMTP_PASSWORD= |cut -d= -f2-)"

	USE_TRAEFIK=true

	cat >/federated/apps/plane/.env <<'EOF'
APP_DOMAIN=plane.@DOMAIN@
IMAGE_VERSION=@VERSION@
VALKEY_RELEASE=7.2.5-alpine
RABBITMQ_RELEASE=3.13.6-management-alpine
MINIO_RELEASE=RELEASE.2024-12-18T13-15-44Z

WEB_REPLICAS=1
SPACE_REPLICAS=1
ADMIN_REPLICAS=1
API_REPLICAS=1

NGINX_PORT=80
WEB_URL=http://${APP_DOMAIN}
DEBUG=0
SENTRY_DSN=
SENTRY_ENVIRONMENT=production
CORS_ALLOWED_ORIGINS=http://${APP_DOMAIN}
API_BASE_URL=http://api:8000

#DB SETTINGS
PGHOST=postgresql
PGDATABASE=plane
POSTGRES_USER=plane
POSTGRES_PASSWORD=@POSTGRES_PASSWORD@
POSTGRES_DB=plane
POSTGRES_PORT=5432
PGDATA=/var/lib/postgresql/data
DATABASE_URL=

# REDIS SETTINGS
REDIS_HOST=plane-redis
REDIS_PORT=6379
REDIS_URL=

# RabbitMQ Settings
RABBITMQ_HOST=plane-mq
RABBITMQ_PORT=5672
RABBITMQ_USER=plane
RABBITMQ_PASSWORD=plane
RABBITMQ_VHOST=plane
AMQP_URL=

# Secret Key
SECRET_KEY=60gp0byfz2dvffa45cxl20p1scy9xbpf6d8c5y0geejgkyp1b5

# DATA STORE SETTINGS
USE_MINIO=1
AWS_REGION=
AWS_ACCESS_KEY_ID=access-key
AWS_SECRET_ACCESS_KEY=secret-key
AWS_S3_ENDPOINT_URL=http://plane-minio:9000
AWS_S3_BUCKET_NAME=uploads
MINIO_ROOT_USER=access-key
MINIO_ROOT_PASSWORD=secret-key
BUCKET_NAME=uploads
FILE_SIZE_LIMIT=5242880

# Gunicorn Workers
GUNICORN_WORKERS=1

# Email
EMAIL_HOST=mail.@DOMAIN@
EMAIL_HOST_USER=fcore@@DOMAIN@
EMAIL_HOST_PASSWORD=@EMAIL_PASSWORD@
EMAIL_PORT=587
EMAIL_FROM=admin@@DOMAIN@
EMAIL_USE_TLS=1
EMAIL_USE_SSL=0

# UNCOMMENT `DOCKER_PLATFORM` IF YOU ARE ON `ARM64` AND DOCKER IMAGE IS NOT AVAILABLE FOR RESPECTIVE `IMAGE_VERSION`
# DOCKER_PLATFORM=linux/amd64

DOCKERHUB_USER=makeplane
PULL_POLICY=if_not_present
CUSTOM_BUILD=false
EOF

	cat > /federated/apps/plane/docker-compose.yml <<'EOF'
x-app-env: &app-env
  environment:
    - NGINX_PORT=${NGINX_PORT:-80}
    - WEB_URL=${WEB_URL:-http://localhost}
    - DEBUG=${DEBUG:-0}
    - SENTRY_DSN=${SENTRY_DSN:-""}
    - SENTRY_ENVIRONMENT=${SENTRY_ENVIRONMENT:-"production"}
    - CORS_ALLOWED_ORIGINS=${CORS_ALLOWED_ORIGINS:-}
    # Gunicorn Workers
    - GUNICORN_WORKERS=${GUNICORN_WORKERS:-1}
    #DB SETTINGS
    - PGHOST=${PGHOST:-postgresql}
    - PGDATABASE=${PGDATABASE:-plane}
    - POSTGRES_USER=${POSTGRES_USER:-plane}
    - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-@POSTGRES_PASSWORD@}
    - POSTGRES_DB=${POSTGRES_DB:-plane}
    - POSTGRES_PORT=${POSTGRES_PORT:-5432}
    - PGDATA=${PGDATA:-/var/lib/postgresql/data}
    - DATABASE_URL=${DATABASE_URL:-postgresql://plane:@POSTGRES_PASSWORD@@postgresql/plane}
    # REDIS SETTINGS
    - REDIS_HOST=${REDIS_HOST:-plane-redis}
    - REDIS_PORT=${REDIS_PORT:-6379}
    - REDIS_URL=${REDIS_URL:-redis://plane-redis:6379/}

    # RabbitMQ Settings
    - RABBITMQ_HOST=${RABBITMQ_HOST:-plane-mq}
    - RABBITMQ_PORT=${RABBITMQ_PORT:-5672}
    - RABBITMQ_DEFAULT_USER=${RABBITMQ_USER:-plane}
    - RABBITMQ_DEFAULT_PASS=${RABBITMQ_PASSWORD:-plane}
    - RABBITMQ_DEFAULT_VHOST=${RABBITMQ_VHOST:-plane}
    - RABBITMQ_VHOST=${RABBITMQ_VHOST:-plane}
    - AMQP_URL=${AMQP_URL:-amqp://plane:plane@plane-mq:5672/plane}
    # Application secret
    - SECRET_KEY=${SECRET_KEY:-60gp0byfz2dvffa45cxl20p1scy9xbpf6d8c5y0geejgkyp1b5}
    # DATA STORE SETTINGS
    - USE_MINIO=${USE_MINIO:-1}
    - AWS_REGION=${AWS_REGION:-}
    - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-"access-key"}
    - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-"secret-key"}
    - AWS_S3_ENDPOINT_URL=${AWS_S3_ENDPOINT_URL:-http://plane-minio:9000}
    - AWS_S3_BUCKET_NAME=${AWS_S3_BUCKET_NAME:-uploads}
    - MINIO_ROOT_USER=${MINIO_ROOT_USER:-"access-key"}
    - MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD:-"secret-key"}
    - BUCKET_NAME=${BUCKET_NAME:-uploads}
    - FILE_SIZE_LIMIT=${FILE_SIZE_LIMIT:-5242880}
    # Live server env
    - API_BASE_URL=${API_BASE_URL:-http://api:8000}

services:
  web:
    <<: *app-env
    image: ${DOCKERHUB_USER:-makeplane}/plane-frontend:${IMAGE_VERSION:-stable}
    platform: ${DOCKER_PLATFORM:-}
    expose:
      - 3000
    ports:
      - 3000:3000
    env_file:
      - .env
EOF

	if $USE_TRAEFIK; then
		cat >> /federated/apps/plane/docker-compose.yml <<'EOF'
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.plane-web.rule=Host(`plane.@DOMAIN@`)"
      - "traefik.http.routers.plane-web.entrypoints=websecure"
      - "traefik.http.routers.plane-web.tls.certresolver=letsencrypt"
      - "traefik.http.services.plane-web.loadbalancer.server.port=3000"
EOF
	fi

	cat >> /federated/apps/plane/docker-compose.yml <<'EOF'
    networks:
      core:
        ipv4_address: 192.168.0.50
    pull_policy: if_not_present
    restart: unless-stopped
    command: node web/server.js web
    deploy:
      replicas: ${WEB_REPLICAS:-1}
    depends_on:
      - api
      - worker

  space:
    <<: *app-env
    image: ${DOCKERHUB_USER:-makeplane}/plane-space:${IMAGE_VERSION:-stable}
    platform: ${DOCKER_PLATFORM:-}
    env_file:
      - .env
    networks:
      core:
        ipv4_address: 192.168.0.51
EOF

	if $USE_TRAEFIK; then
		cat >> /federated/apps/plane/docker-compose.yml <<'EOF'
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.plane-space.rule=Host(`plane.@DOMAIN@`) && PathPrefix(`/spaces`)"
      - "traefik.http.routers.plane-space.entrypoints=websecure"
      - "traefik.http.routers.plane-space.tls.certresolver=letsencrypt"
      - "traefik.http.services.plane-space.loadbalancer.server.port=3000"
EOF
	fi

	cat >> /federated/apps/plane/docker-compose.yml <<'EOF'
    pull_policy: if_not_present
    restart: unless-stopped
    command: node space/server.js space
    deploy:
      replicas: ${SPACE_REPLICAS:-1}
    depends_on:
      - api
      - worker
      - web

  admin:
    <<: *app-env
    image: ${DOCKERHUB_USER:-makeplane}/plane-admin:${IMAGE_VERSION:-stable}
    platform: ${DOCKER_PLATFORM:-}
    env_file:
      - .env
    networks:
      core:
        ipv4_address: 192.168.0.52
EOF

	if $USE_TRAEFIK; then
		cat >> /federated/apps/plane/docker-compose.yml <<'EOF'
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.plane-admin.rule=Host(`plane.@DOMAIN@`) && PathPrefix(`/god-mode`)"
      - "traefik.http.routers.plane-admin.entrypoints=websecure"
      - "traefik.http.routers.plane-admin.tls.certresolver=letsencrypt"
      - "traefik.http.services.plane-admin.loadbalancer.server.port=3000"
EOF
	fi

	cat >> /federated/apps/plane/docker-compose.yml <<'EOF'
    pull_policy: if_not_present
    restart: unless-stopped
    command: node admin/server.js admin
    deploy:
      replicas: ${ADMIN_REPLICAS:-1}
    depends_on:
      - api
      - web

  live:
    <<: *app-env
    image: ${DOCKERHUB_USER:-makeplane}/plane-live:${IMAGE_VERSION:-stable}
    platform: ${DOCKER_PLATFORM:-}
    env_file:
      - .env
    networks:
      core:
        ipv4_address: 192.168.0.53
EOF

	if $USE_TRAEFIK; then
		cat >> /federated/apps/plane/docker-compose.yml <<'EOF'
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.plane-live.rule=Host(`plane.@DOMAIN@`) && PathPrefix(`/live`)"
      - "traefik.http.routers.plane-live.entrypoints=websecure"
      - "traefik.http.routers.plane-live.tls.certresolver=letsencrypt"
      - "traefik.http.services.plane-live.loadbalancer.server.port=3000"
EOF
	fi

	cat >> /federated/apps/plane/docker-compose.yml <<'EOF'
    pull_policy: if_not_present
    restart: unless-stopped
    command: node live/dist/server.js live
    deploy:
      replicas: ${LIVE_REPLICAS:-1}
    depends_on:
      - api
      - web

  api:
    <<: *app-env
    image: ${DOCKERHUB_USER:-makeplane}/plane-backend:${IMAGE_VERSION:-stable}
    platform: ${DOCKER_PLATFORM:-}
    env_file:
      - .env
    networks:
      core:
        ipv4_address: 192.168.0.54
EOF

	if $USE_TRAEFIK; then
		cat >> /federated/apps/plane/docker-compose.yml <<'EOF'
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.plane-api.rule=Host(`plane.@DOMAIN@`) && (PathPrefix(`/api`) || PathPrefix(`/auth`))"
      - "traefik.http.routers.plane-api.entrypoints=websecure"
      - "traefik.http.routers.plane-api.tls.certresolver=letsencrypt"
      - "traefik.http.services.plane-api.loadbalancer.server.port=8000"
EOF
	fi

	cat >> /federated/apps/plane/docker-compose.yml <<'EOF'
    pull_policy: if_not_present
    restart: unless-stopped
    command: ./bin/docker-entrypoint-api.sh
    deploy:
      replicas: ${API_REPLICAS:-1}
    volumes:
      - logs_api:/code/plane/logs
    depends_on:
      - plane-redis
      - plane-mq


  worker:
    <<: *app-env
    image: ${DOCKERHUB_USER:-makeplane}/plane-backend:${IMAGE_VERSION:-stable}
    platform: ${DOCKER_PLATFORM:-}
    env_file:
      - .env
    networks:
      core:
        ipv4_address: 192.168.0.55
    pull_policy: if_not_present
    restart: unless-stopped
    command: ./bin/docker-entrypoint-worker.sh
    volumes:
      - logs_worker:/code/plane/logs
    depends_on:
      - api
      - plane-redis
      - plane-mq

  beat-worker:
    <<: *app-env
    image: ${DOCKERHUB_USER:-makeplane}/plane-backend:${IMAGE_VERSION:-stable}
    platform: ${DOCKER_PLATFORM:-}
    env_file:
      - .env
    networks:
      core:
        ipv4_address: 192.168.0.56
    pull_policy: if_not_present
    restart: unless-stopped
    command: ./bin/docker-entrypoint-beat.sh
    volumes:
      - logs_beat-worker:/code/plane/logs
    depends_on:
      - api
      - plane-redis
      - plane-mq

  migrator:
    <<: *app-env
    image: ${DOCKERHUB_USER:-makeplane}/plane-backend:${IMAGE_VERSION:-stable}
    platform: ${DOCKER_PLATFORM:-}
    env_file:
      - .env
    networks:
      core:
        ipv4_address: 192.168.0.57
    pull_policy: if_not_present
    restart: "no"
    command: ./bin/docker-entrypoint-migrator.sh
    volumes:
      - logs_migrator:/code/plane/logs
    depends_on:
      - plane-redis

  plane-redis:
    <<: *app-env
    image: valkey/valkey:${VALKEY_RELEASE:-7.2.5-alpine}
    env_file:
      - .env
    networks:
      core:
        ipv4_address: 192.168.0.58
    pull_policy: if_not_present
    restart: unless-stopped
    volumes:
      - redisdata:/data

  plane-mq:
    <<: *app-env
    image: rabbitmq:${RABBITMQ_RELEASE:-3.13.6-management-alpine}
    env_file:
      - .env
    networks:
      core:
        ipv4_address: 192.168.0.59
    restart: always
    volumes:
      - rabbitmq_data:/var/lib/rabbitmq

  plane-minio:
    <<: *app-env
    image: minio/minio:${MINIO_RELEASE:-RELEASE.2024-12-18T13-15-44Z}
    env_file:
      - .env
    networks:
      core:
        ipv4_address: 192.168.0.60
EOF

	if $USE_TRAEFIK; then
		cat >> /federated/apps/plane/docker-compose.yml <<'EOF'
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.plane-uploads.rule=Host(`plane.@DOMAIN@`) && PathPrefix(`/uploads`)"
      - "traefik.http.routers.plane-uploads.entrypoints=websecure"
      - "traefik.http.routers.plane-uploads.tls.certresolver=letsencrypt"
      - "traefik.http.services.plane-uploads.loadbalancer.server.port=9000"
EOF
	fi

	cat >> /federated/apps/plane/docker-compose.yml <<'EOF'
    pull_policy: if_not_present
    restart: unless-stopped
    command: server /export --console-address ":9090"
    volumes:
      - uploads:/export
EOF

	if ! $USE_TRAEFIK; then
		cat >> /federated/apps/plane/docker-compose.yml <<'EOF'
  proxy:
    <<: *app-env
    image: ${DOCKERHUB_USER:-makeplane}/plane-proxy:${IMAGE_VERSION:-stable}
    env_file:
      - .env
    platform: ${DOCKER_PLATFORM:-}
    pull_policy: if_not_present
    restart: unless-stopped
    ports:
      - ${NGINX_PORT}:80
    depends_on:
      - web
      - api
      - space
EOF
	fi

	cat >> /federated/apps/plane/docker-compose.yml <<'EOF'
volumes:
  redisdata:
  
  uploads:
  logs_api:
  logs_worker:
  logs_beat-worker:
  logs_migrator:
  rabbitmq_data:

networks:
  core:
    external: true
EOF
	sed -i -e "s,@DOMAIN@,${DOMAIN},g" \
	       -e "s,@VERSION@,$(current_version plane),g" \
	       -e "s,@POSTGRES_PASSWORD@,${POSTGRES_PASSWORD},g" \
	       -e "s,@EMAIL_PASSWORD@,${EMAIL_PASSWORD},g" \
		/federated/apps/plane/docker-compose.yml \
		/federated/apps/plane/.env
	chmod 600 /federated/apps/plane/.env

	# Create database and user in postgresql
	SQL="docker exec postgresql psql --csv -U postgres"
	$SQL -c "CREATE DATABASE plane" &> /dev/null
	$SQL -c "CREATE USER plane WITH PASSWORD '${POSTGRES_PASSWORD}'" &> /dev/null
	$SQL -c "GRANT ALL PRIVILEGES ON DATABASE plane TO plane" &> /dev/null
	unset POSTGRES_PASSWORD

	# migrator is usually started at the same time as plane - we need to
	# run it manually once to create the initial database so we can make
	# modifications to it (like creating the admin user) before plane is
	# run the regular way
	pushd /federated/apps/plane
	docker compose up -d migrator
	popd
	# Wait for the migrator to exit -- at that point, the database should be
	# ready for manipulation
	echo "Waiting for completion of the initial plane database - this will take some time."
	while [ -n "$(docker ps -q -f name=plane-migrator-1)" ]; do
		sleep 1s
		echo -n .
	done
	echo

	dnf -y --refresh install python-passlib || (apt update ; apt -y install python3-passlib)

	INSTANCE_ID=$(random xxxxxxxxxxxxxxxxxxxxxxxx)
	INSTANCE_UUID=$(random xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
	USER_UUID=$(random xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
	ADMIN_UUID=$(random xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
	NOTIFICATION_UUID=$(random xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
	PROFILE_UUID=$(random xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
	SIGNUP_UUID=$(random xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
	TOKEN=$(random xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)
	ADMINPASS=$(grep ADMINPASS= /var/lib/cloud/instances/[0-9]*/cloud-config.txt |cut -d= -f2- |cut -d'"' -f2 |tr -d '\\')
	ENCODED_PASSWORD=$(python3 -c "from passlib.hash import django_pbkdf2_sha256; print(django_pbkdf2_sha256.hash('$ADMINPASS'))")
	# FIXME don't hardcode 0.24.0
	cat >/federated/apps/postgresql/data/var/lib/postgresql/data/plane-initial-user.sql <<EOF
INSERT INTO instances(created_at, updated_at, id,               instance_name,                instance_id,    current_version, last_checked_at, is_telemetry_enabled, is_support_required, is_setup_done, is_signup_screen_visited, is_verified, domain,    latest_version, edition,           is_test)
	       VALUES(NOW(),      NOW(),      '$INSTANCE_UUID', 'Federated Computer - Plane', '$INSTANCE_ID', '0.24.0',        NOW(),           FALSE,                FALSE,               TRUE,          TRUE,                     TRUE,        '$DOMAIN', '0.24.0',       'PLANE_COMMUNITY', FALSE);
UPDATE instances SET instance_name='Federated Computer - Plane';
UPDATE instances SET is_telemetry_enabled=FALSE;
UPDATE instances SET is_setup_done=TRUE;
INSERT INTO users (password,            last_login, id,           username, email,           first_name, last_name, avatar, date_joined, created_at, updated_at, last_location, created_location, is_superuser, is_managed, is_password_expired, is_active, is_staff, is_email_verified, is_password_autoset, token,    user_timezone, last_active, last_login_time, last_logout_time, last_login_ip,  last_logout_ip, last_login_medium, last_login_uagent,      is_bot, display_name)
	    VALUES('$ENCODED_PASSWORD', NOW(),      '$USER_UUID', 'admin',  'admin@$DOMAIN', 'Plane',    'Admin',   '',     NOW(),       NOW(),      NOW(),      '',            '',               TRUE,         FALSE,      FALSE,               TRUE,      TRUE,     TRUE,              FALSE,               '$TOKEN', 'UTC',         NOW(),       NOW(),           NOW(),            '192.168.0.13', '192.168.0.13', 'email',           'Federated Signup/1.0', FALSE,  'admin');
INSERT INTO user_notification_preferences(created_at, updated_at, id,                   property_change, state_change, comment, mention, issue_completed, user_id)
				   VALUES(NOW(),      NOW(),      '$NOTIFICATION_UUID', FALSE,           FALSE,        FALSE,   FALSE,   FALSE,           '$USER_UUID');
INSERT INTO profiles(created_at, updated_at, id,            theme, is_tour_completed, onboarding_step,                                                                                                use_case, role, is_onboarded, billing_address_country, has_billing_address, company_name,         user_id)
	      VALUES(NOW(),      NOW(),      '$PROFILE_UUID', '{}',  FALSE,             '{"workspace_join": false, "profile_complete": false, "workspace_create": false, "workspace_invite": false}', '',       '',   FALSE,        'INDIA',                 FALSE,               '$DOMAIN',            '$USER_UUID');
INSERT INTO instance_admins(created_at, updated_at, id,            role, is_verified, instance_id,      user_id)
                     VALUES(NOW(),      NOW(),      '$ADMIN_UUID', 20,   TRUE,        '$INSTANCE_UUID', '$USER_UUID');
INSERT INTO instance_configurations(created_at, updated_at, id,             key,             value, category,         is_encrypted)
			     VALUES(NOW(),      NOW(),      '$SIGNUP_UUID', 'ENABLE_SIGNUP', '0',   'AUTHENTICATION', FALSE);
UPDATE instance_configurations SET value=0 WHERE key='ENABLE_SIGNUP';
EOF
	$SQL plane -f /var/lib/postgresql/data/plane-initial-user.sql
#	rm /federated/apps/postgresql/data/var/lib/postgresql/data/plane-initial-user.sql

	echo -ne "done."
}
start_plane() {
	# Start service with command to make sure it's up before proceeding
#	start_service "plane" "nc -z 192.168.0.50 3000 &> /dev/null" "7"
	/federated/bin/start plane
	echo -ne "done."
}
uninstall_plane() {
	docker exec postgresql psql -U postgres -c "DROP DATABASE plane" &> /dev/null
	docker exec postgresql psql -U postgres -c "DROP USER plane" &> /dev/null
	rm -rf /federated/apps/plane
}
email_plane() {
	echo -ne "* Sending email to customer.."
	spin &
	SPINPID=$!

	cat > /federated/apps/mail/data/root/certs/mailfile <<EOF
<html>
<img src="https://www.federated.computer/wp-content/uploads/2023/11/logo.png" alt="" /><br>
<p>
<h4>Plane is now installed on $DOMAIN</h4>
<p>
Here is your applications chart with on how to access this service:<br>
<p>
<h4>Applications</h4>
<style type="text/css">
.tg  {border-collapse:collapse;border-spacing:0;}
.tg td{border-color:black;border-style:solid;border-width:1px;font-family:Arial, sans-serif;font-size:14px;
  overflow:hidden;padding:10px 5px;word-break:normal;}
.tg th{border-color:black;border-style:solid;border-width:1px;font-family:Arial, sans-serif;font-size:14px;
  font-weight:normal;overflow:hidden;padding:10px 5px;word-break:normal;}
.tg .tg-cul6{border-color:inherit;color:#340096;text-align:left;text-decoration:underline;vertical-align:top}
.tg .tg-acii{background-color:#FFF;border-color:inherit;color:#333;text-align:left;vertical-align:top}
.tg .tg-0hty{background-color:#000000;border-color:inherit;color:#ffffff;font-weight:bold;text-align:left;vertical-align:top}
.tg .tg-kwiq{border-color:inherit;color:#000000;text-align:left;vertical-align:top;word-wrap:break-word}
.tg .tg-0pky{border-color:inherit;text-align:left;vertical-align:top}
</style>
<table class="tg" style="undefined;table-layout: fixed; width: 996px">
<colgroup>
<col style="width: 101.333333px">
<col style="width: 203.333333px">
<col style="width: 282.333333px">
<col style="width: 185.33333px">
<col style="width: 78.333333px">
<col style="width: 220.333333px">
</colgroup>
<thead>
  <tr>
    <th class="tg-0hty">Service</th>
    <th class="tg-0hty">Link</th>
    <th class="tg-0hty">User / Pass</th>
    <th class="tg-0hty">Access</th>
    <th class="tg-0hty">Docs</th>
    <th class="tg-0hty">Description</th>
  </tr>
</thead>
<tbody>
  <tr>
    <td class="tg-kwiq">Plane</td>
    <td class="tg-kwiq"><a href="https://plane.$DOMAIN" target="_blank" rel="noopener noreferrer"><span style="color:#340096">plane.$DOMAIN</span></a></td>
    <td class="tg-kwiq">admin@$DOMAIN<br>admin password above</td>
    <td class="tg-kwiq">User access is separate from panel. Use the admin account to login and then invite other users</td>
    <td class="tg-kwiq"><a href="https://documentation.federated.computer/docs/getting_started/welcome/" target="_blank" rel="noopener noreferrer"><span style="color:#340096">Click here</span></a></td>
    <td class="tg-kwiq">Plane is a flexible project management tool that helps teams plan, track, and manage their work more efficiently. It’s built to grow with you, offering features like issue tracking, sprint management, time tracking, knowledge management, analytics and more. These tools help your team stay organized, keep things clear, and stay aligned throughout the project.</td>
  </tr>
</tbody>
</table>
<h4>Thanks for your support!</h4>
<p>
Thank you for your support of Federated Computer. We really appreciate it and hope you have a very successful
time with Federated Core.
<p>
Again, if we can be of any assistance, please don't hesitate to get in touch.
<p>
Support: https://support.federated.computer<br>
Phone: (970) 722-8715<br>
Email: support@federated.computer<br>
<p>
It's <b>your</b> computer. Let's make it work for you!
</html>
EOF

	# Send out e-mail from mail container with details
	docker exec mail bash -c "mail -r admin@$DOMAIN -a \"Content-type: text/html\" -s \"Application installed on $DOMAIN\" $EMAIL < /root/certs/mailfile"
	rm /federated/apps/mail/data/root/certs/mailfile

	kill -9 $SPINPID &> /dev/null
	echo -ne "done.\n"
}
