Files
mail-autoconfig/app.py
mifi f643efb220
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone Build is passing
One last tweak
2025-07-24 12:07:31 -03:00

173 lines
5.6 KiB
Python

from flask import Flask, request, Response
import jinja2
app = Flask(__name__)
env = jinja2.Environment(
loader=jinja2.FileSystemLoader('templates'),
autoescape=jinja2.select_autoescape(['xml'])
)
@app.route('/')
def index():
subdomain = request.host.split('.', 1)[0]
domain = request.host.split('.', 1)[1] if '.' in request.host else request.host
base_html = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{title}</title>
<style>
* {{ margin: 0; padding: 0; box-sizing: border-box; }}
body {{
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
color: #333;
}}
.container {{
background: white;
padding: 2rem;
border-radius: 12px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
max-width: 500px;
width: 90%;
text-align: center;
}}
h1 {{
color: #2c3e50;
margin-bottom: 1rem;
font-size: 1.8rem;
}}
.service-type {{
background: #3498db;
color: white;
padding: 0.5rem 1rem;
border-radius: 20px;
display: inline-block;
margin-bottom: 1rem;
font-size: 0.9rem;
font-weight: 500;
}}
.domain {{
background: #f8f9fa;
padding: 0.5rem;
border-radius: 6px;
margin: 1rem 0;
font-family: 'Monaco', 'Courier New', monospace;
color: #495057;
}}
.endpoint {{
background: #e8f5e8;
border: 1px solid #28a745;
border-radius: 6px;
padding: 1rem;
margin: 1rem 0;
}}
.endpoint-label {{
font-weight: 600;
color: #28a745;
margin-bottom: 0.5rem;
}}
.endpoint a {{
color: #007bff;
text-decoration: none;
font-family: 'Monaco', 'Courier New', monospace;
word-break: break-all;
}}
.endpoint a:hover {{
text-decoration: underline;
}}
.status-link {{
display: inline-block;
margin-top: 1rem;
padding: 0.5rem 1rem;
background: #6c757d;
color: white;
text-decoration: none;
border-radius: 6px;
transition: background 0.3s;
}}
.status-link:hover {{
background: #545b62;
}}
.icon {{
font-size: 2rem;
margin-bottom: 1rem;
}}
</style>
</head>
<body>
<div class="container">
<div class="icon">{icon}</div>
<span class="service-type">{service_type}</span>
<h1>{title}</h1>
<div class="domain">Domain: <strong>{domain}</strong></div>
{content}
<a href="/ping" class="status-link">📊 Service Status</a>
</div>
</body>
</html>
"""
if subdomain == 'autoconfig':
return base_html.format(
title="Mail Autoconfig Service",
service_type="Mozilla Thunderbird",
icon="🔧",
domain=domain,
content=f'''
<div class="endpoint">
<div class="endpoint-label">Thunderbird Autoconfig Endpoint:</div>
<a href="/mail/config-v1.1.xml">https://{request.host}/mail/config-v1.1.xml</a>
</div>
'''
)
elif subdomain == 'autodiscover':
return base_html.format(
title="Mail Autodiscover Service",
service_type="Microsoft Outlook",
icon="🔍",
domain=domain,
content=f'''
<div class="endpoint">
<div class="endpoint-label">Outlook Autodiscover Endpoint:</div>
<a href="/Autodiscover/Autodiscover.xml">https://{request.host}/Autodiscover/Autodiscover.xml</a>
</div>
'''
)
else:
return base_html.format(
title="Mail Configuration Service",
service_type="Error",
icon="",
domain="Invalid",
content='''
<div style="color: #dc3545; padding: 1rem;">
<strong>Invalid subdomain!</strong><br>
Please use <code>autoconfig.domain.com</code> or <code>autodiscover.domain.com</code>
</div>
'''
), 400
@app.route('/ping')
def ping():
return "✅ Mail Autoconfig Service is running."
@app.route('/mail/config-v1.1.xml')
def thunderbird_config():
domain = request.host.split('.', 1)[1]
xml = env.get_template('config-v1.1.xml.j2').render(DOMAIN=domain)
return Response(xml, mimetype='application/xml')
@app.route('/Autodiscover/Autodiscover.xml', methods=['POST','GET'])
def outlook_autodiscover():
domain = request.host.split('.', 1)[1]
xml = env.get_template('Autodiscover.xml.j2').render(DOMAIN=domain)
return Response(xml, mimetype='text/xml')