hns-links/main.py

374 lines
13 KiB
Python
Raw Normal View History

2024-02-24 18:47:23 +11:00
from flask import Flask, make_response, redirect, request, jsonify, render_template, send_from_directory, render_template_string
import os
import dotenv
import requests
import datetime
import json
import render
import secrets
import nginx
app = Flask(__name__)
dotenv.load_dotenv()
# Get site domains
DOMAINS = os.getenv('DOMAINS')
DOMAINS = json.loads(DOMAINS)
# Add local domains
# DOMAINS.append('localhost:5000')
DOMAINS.append('127.0.0.1:5000')
IP = "0.0.0.0"
try:
IP = requests.get('https://ipinfo.io/ip').text.strip()
except:
IP = "Error"
# Load cookies
cookies = []
if os.path.isfile('cookies.json'):
with open('cookies.json') as file:
cookies = json.load(file)
else:
with open('cookies.json', 'w') as file:
json.dump(cookies, file)
if not os.path.isdir('avatars'):
os.mkdir('avatars')
if not os.path.isdir('sites'):
os.mkdir('sites')
if not os.path.isdir('certs'):
os.mkdir('certs')
#Assets routes
@app.route('/assets/<path:path>')
def send_report(path):
return send_from_directory('templates/assets', path)
@app.route('/favicon.png')
def faviconPNG():
return send_from_directory('templates/assets/img', 'favicon.png')
# Main routes
@app.route('/')
def index():
if request.host in DOMAINS:
if 'auth' in request.cookies:
auth = request.cookies['auth']
for i in cookies:
if i['cookie'] == auth:
return render_template('index.html',varo="window.location = '/site';", year=datetime.datetime.now().year)
return render_template('index.html',varo=render.varo_login(), year=datetime.datetime.now().year)
# Remove any ports
host = request.host.split(':')[0]
# Get content from site
if os.path.isfile(f'sites/{host}.json'):
with open(f'sites/{host}.json') as file:
data = json.load(file)
return render.site(data, True)
2024-02-24 18:47:23 +11:00
return redirect(f'https://{DOMAINS[0]}')
@app.route('/site')
def site():
# Get auth domain
if 'auth' not in request.cookies:
return redirect('/')
auth = request.cookies['auth']
for i in cookies:
if i['cookie'] == auth:
# Load site content
if os.path.isfile(f'sites/{i["name"]}.json'):
with open(f'sites/{i["name"]}.json') as file:
data = json.load(file)
preview = render.preview(data)
else:
with open(f'sites/example.json') as file:
data = json.load(file)
preview = render.preview(data)
data = {
'title': '',
'link_0': '',
'link_1': '',
'link_2': '',
'link_3': '',
'link_0_url': '',
'link_1_url': '',
'link_2_url': '',
'link_3_url': '',
'image': '',
"bg_0": "#001665",
"bg_1": "#000000",
"fg_0": "#ffffff",
"btn_bg": "#2c54cf",
"btn_fg": "#ffffff",
"socials": [],
"address": []
2024-02-24 18:47:23 +11:00
}
title = data['title']
link_0 = data['link_0']
link_1 = data['link_1']
link_2 = data['link_2']
link_3 = data['link_3']
link_0_url = data['link_0_url']
link_1_url = data['link_1_url']
link_2_url = data['link_2_url']
link_3_url = data['link_3_url']
fg_0 = data['fg_0']
bg_0 = data['bg_0']
bg_1 = data['bg_1']
btn_bg = data['btn_bg']
btn_fg = data['btn_fg']
socials = data['socials']
address = data['address']
# Convert socials to dict
socials = {i['name']: i['url'] for i in socials}
address = {i['token']: i['address'] for i in address}
tlsa = data['tlsa'] if 'tlsa' in data else ''
ip = IP
return render_template('site.html', year=datetime.datetime.now().year, domain=i['name'],
title=title, link_0=link_0, link_1=link_1, link_2=link_2, link_3=link_3,
link_0_url=link_0_url, link_1_url=link_1_url, link_2_url=link_2_url,
link_3_url=link_3_url, fg_0=fg_0, bg_0=bg_0, bg_1=bg_1, btn_bg=btn_bg, btn_fg=btn_fg,
socials=socials,address=address,preview=preview,tlsa=tlsa,ip=ip)
response = make_response(redirect('/'))
response.set_cookie('auth', '', expires=0)
return response
@app.route('/site', methods=['POST'])
def site_post():
if 'auth' not in request.cookies:
return redirect('/')
auth = request.cookies['auth']
for i in cookies:
if i['cookie'] == auth:
# Get site content
if os.path.isfile(f'sites/{i["name"]}.json'):
with open(f'sites/{i["name"]}.json') as file:
data = json.load(file)
else:
with open(f'sites/example.json') as file:
data = {}
# Save site content
data['title'] = request.form['title']
data['link_0'] = request.form['link_0']
data['link_1'] = request.form['link_1']
data['link_2'] = request.form['link_2']
data['link_3'] = request.form['link_3']
data['link_0_url'] = request.form['link_0_url']
data['link_1_url'] = request.form['link_1_url']
data['link_2_url'] = request.form['link_2_url']
data['link_3_url'] = request.form['link_3_url']
data['bg_0'] = request.form['bg_0']
data['bg_1'] = request.form['bg_1']
data['fg_0'] = request.form['fg_0']
data['btn_bg'] = request.form['btn_bg']
data['btn_fg'] = request.form['btn_fg']
socials = []
socials.append({'name': 'email', 'url': request.form['email']})
socials.append({'name': 'twitter', 'url': request.form['twitter']})
socials.append({'name': 'github', 'url': request.form['github']})
socials.append({'name': 'youtube', 'url': request.form['youtube']})
address = []
address.append({'token': 'hns', 'address': request.form['hns']})
address.append({'token': 'eth', 'address': request.form['eth']})
address.append({'token': 'btc', 'address': request.form['btc']})
address.append({'token': 'sol', 'address': request.form['sol']})
# Remove empty socials and addresses
socials = [i for i in socials if i['url'] != '']
data['socials'] = socials
address = [i for i in address if i['address'] != '']
data['address'] = address
if 'image' in request.files:
if request.files['image'].filename != '' and request.files['image'].filename != None:
# Make sure the file is an image
file = request.files['image']
extension = file.filename.split('.')[-1]
file.save(f'avatars/{i["name"]}.' + extension)
data['image'] = f'{i["name"]}.' + extension
2024-02-24 21:48:14 +11:00
else:
if 'image' not in data:
data['image'] = ''
2024-02-24 18:47:23 +11:00
with open(f'sites/{i["name"]}.json', 'w') as file:
json.dump(data, file)
return redirect('/site')
response = make_response(redirect('/'))
response.set_cookie('auth', '', expires=0)
return response
@app.route('/preview')
def site_preview():
if 'auth' not in request.cookies:
return redirect('/')
auth = request.cookies['auth']
for i in cookies:
if i['cookie'] == auth:
# Load site content
if os.path.isfile(f'sites/{i["name"]}.json'):
with open(f'sites/{i["name"]}.json') as file:
data = json.load(file)
else:
with open(f'sites/example.json') as file:
data = json.load(file)
return render.site(data)
response = make_response(redirect('/'))
response.set_cookie('auth', '', expires=0)
return response
@app.route('/publish')
def publish():
if 'auth' not in request.cookies:
return redirect('/')
auth = request.cookies['auth']
for i in cookies:
if i['cookie'] == auth:
# Load site content
if os.path.isfile(f'sites/{i["name"]}.json'):
with open(f'sites/{i["name"]}.json') as file:
data = json.load(file)
if 'tlsa' in data:
# Site is already published
return redirect('/site')
tlsa = nginx.generate_ssl(i['name'])
data['tlsa'] = tlsa
with open(f'sites/{i["name"]}.json', 'w') as file:
json.dump(data, file)
nginx.write_nginx_conf(i['name'])
return redirect('/site')
response = make_response(redirect('/'))
response.set_cookie('auth', '', expires=0)
return response
@app.route('/.well-known/wallets/<path:path>')
def wallets(path):
# Check if host is in domains
if request.host in DOMAINS:
# Check if user is logged in
if 'auth' not in request.cookies:
return redirect(f'https://{DOMAINS[0]}')
auth = request.cookies['auth']
for i in cookies:
if i['cookie'] == auth:
# Load site content
if os.path.isfile(f'sites/{i["name"]}.json'):
with open(f'sites/{i["name"]}.json') as file:
data = json.load(file)
for i in data['address']:
if i['token'].upper() == path:
# Return as plain text
response = make_response(i['address'])
response.headers['Content-Type'] = 'text/plain'
return response
# Get wallet from domain
host = request.host.split(':')[0]
if os.path.isfile(f'sites/{host}.json'):
with open(f'sites/{host}.json') as file:
data = json.load(file)
for i in data['address']:
if i['token'].upper() == path:
# Return as plain text
response = make_response(i['address'])
response.headers['Content-Type'] = 'text/plain'
return response
return render_template('404.html', year=datetime.datetime.now().year), 404
# region Auth
@app.route('/auth', methods=['POST'])
def auth():
global cookies
auth = login(request)
if auth == False:
return render_template('index.html',varo=render.varo_login(), year=datetime.datetime.now().year, error="Failed to login")
resp = make_response(render_template_string("Success"))
# Gen cookie
auth_cookie = secrets.token_hex(12 // 2)
cookies.append({'name': auth, 'cookie': auth_cookie})
with open('cookies.json', 'w') as file:
json.dump(cookies, file)
resp.set_cookie('auth', auth_cookie)
return resp
@app.route('/logout')
def logout():
global cookies
resp = make_response(redirect('/'))
resp.set_cookie('auth', '', expires=0)
cookies = [i for i in cookies if i['cookie'] != request.cookies['auth']]
with open('cookies.json', 'w') as file:
json.dump(cookies, file)
return resp
def login(request):
dict = request.form.to_dict()
keys = dict.keys()
keys = list(keys)[0]
keys = json.loads(keys)
auth_request = keys['request']
# return login(auth_request)
r = requests.get(f'https://auth.varo.domains/verify/{auth_request}')
r = r.json()
if r['success'] == False:
return False
if 'data' in r:
data = r['data']
if 'name' in data:
return data['name']
return False
# endregion
@app.route('/avatar/<path:path>')
def avatar(path):
return send_from_directory('avatars', path)
@app.route('/token/<path:path>')
def tokens(path):
# Colour is last char
colour = path[-1]
token = path[:-1]
if colour.lower() == 'w':
return send_from_directory('templates/assets/img/tokens', f'{token}W.png')
return send_from_directory('templates/assets/img/tokens', f'{token}.png')
# 404 catch all
@app.errorhandler(404)
def not_found(e):
return render_template('404.html', year=datetime.datetime.now().year), 404
if __name__ == '__main__':
app.run(debug=True, port=5000, host='0.0.0.0')