Compare commits
No commits in common. "de2ffd022a6827777eb46f7c4f4c60e0733b1122" and "754aada478c5d7d9a1a2053b1a84d261cddaade4" have entirely different histories.
de2ffd022a
...
754aada478
179
main.py
179
main.py
@ -8,7 +8,6 @@ import render
|
|||||||
import secrets
|
import secrets
|
||||||
import nginx
|
import nginx
|
||||||
import threading
|
import threading
|
||||||
import nostr as nostr_module
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
dotenv.load_dotenv()
|
dotenv.load_dotenv()
|
||||||
@ -51,10 +50,6 @@ if not os.path.isdir('certs'):
|
|||||||
def send_report(path):
|
def send_report(path):
|
||||||
return send_from_directory('templates/assets', path)
|
return send_from_directory('templates/assets', path)
|
||||||
|
|
||||||
@app.route('/https.js')
|
|
||||||
def httpsJS():
|
|
||||||
return send_from_directory('templates', 'https.js')
|
|
||||||
|
|
||||||
@app.route('/favicon.png')
|
@app.route('/favicon.png')
|
||||||
def faviconPNG():
|
def faviconPNG():
|
||||||
return send_from_directory('templates/assets/img', 'favicon.png')
|
return send_from_directory('templates/assets/img', 'favicon.png')
|
||||||
@ -69,7 +64,7 @@ def index():
|
|||||||
for i in cookies:
|
for i in cookies:
|
||||||
if i['cookie'] == auth:
|
if i['cookie'] == auth:
|
||||||
return render_template('index.html',varo="window.location = '/site';", year=datetime.datetime.now().year)
|
return render_template('index.html',varo="window.location = '/site';", year=datetime.datetime.now().year)
|
||||||
return render_template('index.html',varo=render.hnslogin(), year=datetime.datetime.now().year)
|
return render_template('index.html',varo=render.varo_login(), year=datetime.datetime.now().year)
|
||||||
# Remove any ports
|
# Remove any ports
|
||||||
host = request.host.split(':')[0]
|
host = request.host.split(':')[0]
|
||||||
# Get content from site
|
# Get content from site
|
||||||
@ -77,7 +72,7 @@ def index():
|
|||||||
with open(f'sites/{host}.json') as file:
|
with open(f'sites/{host}.json') as file:
|
||||||
data = json.load(file)
|
data = json.load(file)
|
||||||
|
|
||||||
return render.site(data, host)
|
return render.site(data, True)
|
||||||
return redirect(f'https://{DOMAINS[0]}')
|
return redirect(f'https://{DOMAINS[0]}')
|
||||||
|
|
||||||
@app.route('/site')
|
@app.route('/site')
|
||||||
@ -114,8 +109,7 @@ def site():
|
|||||||
"btn_bg": "#2c54cf",
|
"btn_bg": "#2c54cf",
|
||||||
"btn_fg": "#ffffff",
|
"btn_fg": "#ffffff",
|
||||||
"socials": [],
|
"socials": [],
|
||||||
"address": [],
|
"address": []
|
||||||
"nostrs": []
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -304,104 +298,6 @@ def publish():
|
|||||||
response.set_cookie('auth', '', expires=0)
|
response.set_cookie('auth', '', expires=0)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@app.route('/nostr')
|
|
||||||
def nostr():
|
|
||||||
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)
|
|
||||||
nostr = []
|
|
||||||
if 'nostr' in data:
|
|
||||||
nostr = data['nostr']
|
|
||||||
|
|
||||||
return render_template('nostr.html',year=datetime.datetime.now().year, domain=i['name'],nostr=nostr)
|
|
||||||
|
|
||||||
response = make_response(redirect('/'))
|
|
||||||
response.set_cookie('auth', '', expires=0)
|
|
||||||
return response
|
|
||||||
|
|
||||||
@app.route('/nostr', methods=['POST'])
|
|
||||||
def nostr_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:
|
|
||||||
return redirect('/site')
|
|
||||||
|
|
||||||
nostr = []
|
|
||||||
if 'nostr' in data:
|
|
||||||
nostr = data['nostr']
|
|
||||||
|
|
||||||
# Check for new nostr links
|
|
||||||
if 'new-name' in request.form and 'new-pub' in request.form:
|
|
||||||
name = request.form['new-name']
|
|
||||||
pub = request.form['new-pub']
|
|
||||||
id = len(nostr)
|
|
||||||
for link in nostr:
|
|
||||||
if link['name'] == name:
|
|
||||||
link['pub'] = pub
|
|
||||||
data['nostr'] = nostr
|
|
||||||
with open(f'sites/{i["name"]}.json', 'w') as file:
|
|
||||||
json.dump(data, file)
|
|
||||||
return redirect('/nostr')
|
|
||||||
if link['id'] >= id:
|
|
||||||
id = link['id'] + 1
|
|
||||||
|
|
||||||
nostr.append({'name': name, 'pub': pub, 'id': id})
|
|
||||||
|
|
||||||
|
|
||||||
data['nostr'] = nostr
|
|
||||||
with open(f'sites/{i["name"]}.json', 'w') as file:
|
|
||||||
json.dump(data, file)
|
|
||||||
return redirect('/nostr')
|
|
||||||
|
|
||||||
response = make_response(redirect('/'))
|
|
||||||
response.set_cookie('auth', '', expires=0)
|
|
||||||
return response
|
|
||||||
|
|
||||||
@app.route('/nostr/delete/<int:id>')
|
|
||||||
def nostr_delete(id):
|
|
||||||
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:
|
|
||||||
return redirect('/site')
|
|
||||||
|
|
||||||
nostr = []
|
|
||||||
if 'nostr' in data:
|
|
||||||
nostr = data['nostr']
|
|
||||||
|
|
||||||
nostr = [i for i in nostr if i['id'] != id]
|
|
||||||
data['nostr'] = nostr
|
|
||||||
with open(f'sites/{i["name"]}.json', 'w') as file:
|
|
||||||
json.dump(data, file)
|
|
||||||
return redirect('/nostr')
|
|
||||||
|
|
||||||
response = make_response(redirect('/'))
|
|
||||||
response.set_cookie('auth', '', expires=0)
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/.well-known/wallets/<path:path>')
|
@app.route('/.well-known/wallets/<path:path>')
|
||||||
def wallets(path):
|
def wallets(path):
|
||||||
# Check if host is in domains
|
# Check if host is in domains
|
||||||
@ -436,43 +332,6 @@ def wallets(path):
|
|||||||
response.headers['Content-Type'] = 'text/plain'
|
response.headers['Content-Type'] = 'text/plain'
|
||||||
return response
|
return response
|
||||||
return render_template('404.html', year=datetime.datetime.now().year), 404
|
return render_template('404.html', year=datetime.datetime.now().year), 404
|
||||||
|
|
||||||
@app.route('/.well-known/nostr.json')
|
|
||||||
def nostr_account():
|
|
||||||
# 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)
|
|
||||||
if 'nostr' in data:
|
|
||||||
nostr = data['nostr']
|
|
||||||
# Return as plain text
|
|
||||||
response = make_response(nostr_module.json(nostr))
|
|
||||||
response.headers['Content-Type'] = 'text/plain'
|
|
||||||
response.headers.add('Access-Control-Allow-Origin', '*')
|
|
||||||
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)
|
|
||||||
if 'nostr' in data:
|
|
||||||
nostr = data['nostr']
|
|
||||||
# Return as plain text
|
|
||||||
response = make_response(nostr_module.json(nostr))
|
|
||||||
response.headers['Content-Type'] = 'text/plain'
|
|
||||||
response.headers.add('Access-Control-Allow-Origin', '*')
|
|
||||||
return response
|
|
||||||
return render_template('404.html', year=datetime.datetime.now().year), 404
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/publishing')
|
@app.route('/publishing')
|
||||||
@ -497,38 +356,6 @@ def auth():
|
|||||||
resp.set_cookie('auth', auth_cookie)
|
resp.set_cookie('auth', auth_cookie)
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
@app.route('/auth', methods=['GET'])
|
|
||||||
def auth_get():
|
|
||||||
global cookies
|
|
||||||
|
|
||||||
if 'username' not in request.args:
|
|
||||||
return redirect('/?error=Failed to login&reason=No username')
|
|
||||||
if 'token' not in request.args:
|
|
||||||
return redirect('/?error=Failed to login&reason=No token')
|
|
||||||
|
|
||||||
username = request.args['username']
|
|
||||||
token = request.args['token']
|
|
||||||
|
|
||||||
# Check if user is valid
|
|
||||||
r = requests.get(f'https://login.hns.au/auth/user?token={token}')
|
|
||||||
r = r.json()
|
|
||||||
|
|
||||||
if 'error' in r:
|
|
||||||
return redirect('/?error=Failed to login&reason=' + r['error'])
|
|
||||||
|
|
||||||
if r['username'] != username:
|
|
||||||
return redirect('/?error=Failed to login&reason=Username mismatch')
|
|
||||||
|
|
||||||
auth_cookie = secrets.token_hex(12 // 2)
|
|
||||||
cookies.append({'name': username, 'cookie': auth_cookie})
|
|
||||||
|
|
||||||
with open('cookies.json', 'w') as file:
|
|
||||||
json.dump(cookies, file)
|
|
||||||
|
|
||||||
resp = make_response(redirect('/site'))
|
|
||||||
resp.set_cookie('auth', auth_cookie)
|
|
||||||
return resp
|
|
||||||
|
|
||||||
@app.route('/logout')
|
@app.route('/logout')
|
||||||
def logout():
|
def logout():
|
||||||
global cookies
|
global cookies
|
||||||
|
29
nostr.py
29
nostr.py
@ -1,29 +0,0 @@
|
|||||||
from base64 import b32decode
|
|
||||||
from base64 import b16encode
|
|
||||||
from bech32 import bech32_decode
|
|
||||||
from bech32 import bech32_encode
|
|
||||||
|
|
||||||
B32 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
|
|
||||||
|
|
||||||
def add_padding(base32_len):
|
|
||||||
bits = base32_len * 5
|
|
||||||
padding_size = (8 - (bits % 8)) % 8
|
|
||||||
return padding_size
|
|
||||||
|
|
||||||
def npub_to_hex(npub):
|
|
||||||
hrd, data = bech32_decode(npub)
|
|
||||||
b32_data = [B32[index] for index in data]
|
|
||||||
data_str = "".join(b32_data)
|
|
||||||
data_length = len(data_str)
|
|
||||||
data_str += "=" * add_padding(data_length)
|
|
||||||
decoded_data = b32decode(data_str)
|
|
||||||
b16_encoded_data = b16encode(decoded_data)
|
|
||||||
hex_str = b16_encoded_data.decode("utf-8").lower()
|
|
||||||
return hex_str
|
|
||||||
|
|
||||||
def json(links):
|
|
||||||
names = {}
|
|
||||||
for link in links:
|
|
||||||
names[link['name']] = npub_to_hex(link['pub'])
|
|
||||||
|
|
||||||
return {'names':names}
|
|
12
render.py
12
render.py
@ -11,14 +11,6 @@ def varo_login():
|
|||||||
}
|
}
|
||||||
});'''
|
});'''
|
||||||
|
|
||||||
def hnslogin():
|
|
||||||
# Redirect to https://login.hns.au/auth?return={{scheme}}{{host}}/auth
|
|
||||||
|
|
||||||
return """
|
|
||||||
const { protocol, hostname, port } = window.location;
|
|
||||||
const rootUrl = `${protocol}//${hostname}${port ? `:${port}` : ''}/auth`;
|
|
||||||
window.location.href = `https://login.hns.au/auth?return=${encodeURIComponent(rootUrl)}`;
|
|
||||||
"""
|
|
||||||
|
|
||||||
def preview(data):
|
def preview(data):
|
||||||
title = data['title']
|
title = data['title']
|
||||||
@ -71,7 +63,7 @@ def address_links(addresses,foreground):
|
|||||||
html = ''
|
html = ''
|
||||||
for address in addresses:
|
for address in addresses:
|
||||||
token = address['token'].upper()
|
token = address['token'].upper()
|
||||||
html += f'<a style="margin:5px;" href=".well-known/wallets/{token}" target="_blank">{tokenImage(token,foreground)}</a>'
|
html += f'<a href=".well-known/wallets/{token}" target="_blank">{tokenImage(token,foreground)}</a>'
|
||||||
return html
|
return html
|
||||||
|
|
||||||
def tokenImage(token,foreground):
|
def tokenImage(token,foreground):
|
||||||
@ -99,7 +91,7 @@ def site(data, injectSSL = False):
|
|||||||
|
|
||||||
ssl = ''
|
ssl = ''
|
||||||
if injectSSL:
|
if injectSSL:
|
||||||
ssl = f'<script src="https://{injectSSL}/https.js" async=""></script>'
|
ssl = '<script src="https://nathan.woodburn/https.js" async=""></script>'
|
||||||
page = "page.html"
|
page = "page.html"
|
||||||
if data['image'] == "":
|
if data['image'] == "":
|
||||||
page = "page_no_image.html"
|
page = "page_no_image.html"
|
||||||
|
@ -2,5 +2,4 @@ flask
|
|||||||
python-dotenv
|
python-dotenv
|
||||||
gunicorn
|
gunicorn
|
||||||
requests
|
requests
|
||||||
apscheduler
|
apscheduler
|
||||||
bech32
|
|
@ -5,15 +5,7 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
||||||
<title>HNS Links</title>
|
<title>HNS Links</title>
|
||||||
<meta name="twitter:title" content="HNS Links">
|
|
||||||
<meta name="twitter:image" content="https://links.hns.au/assets/img/dashboard.png">
|
|
||||||
<meta name="twitter:card" content="summary">
|
|
||||||
<meta property="og:type" content="website">
|
|
||||||
<meta property="og:title" content="HNS Links">
|
|
||||||
<meta name="description" content="Create a links page for your domain">
|
<meta name="description" content="Create a links page for your domain">
|
||||||
<meta property="og:description" content="Create a links page for your domain">
|
|
||||||
<meta property="og:image" content="https://links.hns.au/assets/img/dashboard.png">
|
|
||||||
<meta name="twitter:description" content="Create a links page for your domain">
|
|
||||||
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
|
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
|
||||||
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
|
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
|
||||||
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
|
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
|
||||||
|
2
templates/assets/css/styles.min.css
vendored
2
templates/assets/css/styles.min.css
vendored
@ -1 +1 @@
|
|||||||
.video-container{position:relative;padding-bottom:56.25%;padding-top:0;height:0;overflow:hidden}.video-container embed,.video-container iframe,.video-container object{position:absolute;top:0;left:0;width:100%;height:100%}.nostr{margin-top:1em}.social-icons{color:#313437;background-color:#fff;padding:70px 0}@media (max-width:767px){.social-icons{padding:50px 0}}.social-div{display:flex;justify-content:center;align-items:center}.social-list{max-width:100%;display:flex;list-style:none;gap:2.5rem}@media (max-width:500px){.social-list{gap:1.5rem}}@media (max-width:420px){.social-list{gap:0}}.custom-button{max-width:500px}.addresses{margin-bottom:20px;display:flex;justify-content:center;align-items:center}.social-icons i{color:#757980;margin:0 10px;width:60px;height:60px;border:1px solid #c8ced7;text-align:center;border-radius:50%;line-height:60px;display:inline-block}.social-link a{text-decoration:none;width:4.8rem;height:4.8rem;background-color:#f0f9fe;border-radius:50%;display:flex;justify-content:center;align-items:center;position:relative;z-index:1;border:3px solid #f0f9fe;overflow:hidden}.social-link a::before{content:"";position:absolute;width:100%;height:100%;background:#000;z-index:0;scale:1 0;transform-origin:bottom;transition:scale .5s}.social-link:hover a::before{scale:1 1}.icon{font-size:2rem;color:#011827;transition:.5s;z-index:2}.social-link a:hover .icon{color:#fff;transform:rotateY(360deg)}
|
.video-container{position:relative;padding-bottom:56.25%;padding-top:0;height:0;overflow:hidden}.video-container embed,.video-container iframe,.video-container object{position:absolute;top:0;left:0;width:100%;height:100%}.social-icons{color:#313437;background-color:#fff;padding:70px 0}@media (max-width:767px){.social-icons{padding:50px 0}}.social-div{display:flex;justify-content:center;align-items:center}.social-list{max-width:100%;display:flex;list-style:none;gap:2.5rem}@media (max-width:500px){.social-list{gap:1.5rem}}@media (max-width:420px){.social-list{gap:0}}.custom-button{max-width:500px}.addresses{margin-bottom:20px;display:flex;justify-content:center;align-items:center}.social-icons i{color:#757980;margin:0 10px;width:60px;height:60px;border:1px solid #c8ced7;text-align:center;border-radius:50%;line-height:60px;display:inline-block}.social-link a{text-decoration:none;width:4.8rem;height:4.8rem;background-color:#f0f9fe;border-radius:50%;display:flex;justify-content:center;align-items:center;position:relative;z-index:1;border:3px solid #f0f9fe;overflow:hidden}.social-link a::before{content:"";position:absolute;width:100%;height:100%;background:#000;z-index:0;scale:1 0;transform-origin:bottom;transition:scale .5s}.social-link:hover a::before{scale:1 1}.icon{font-size:2rem;color:#011827;transition:.5s;z-index:2}.social-link a:hover .icon{color:#fff;transform:rotateY(360deg)}
|
@ -1,6 +0,0 @@
|
|||||||
if (location.protocol !== 'https:') {
|
|
||||||
location.replace(`https:${location.href.substring(location.protocol.length)}`);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
console.log("Already Https");
|
|
||||||
}
|
|
@ -5,23 +5,7 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
||||||
<title>HNS Links</title>
|
<title>HNS Links</title>
|
||||||
<meta name="twitter:title" content="HNS Links">
|
|
||||||
<meta name="twitter:image" content="https://links.hns.au/assets/img/dashboard.png">
|
|
||||||
<meta name="twitter:card" content="summary">
|
|
||||||
<meta property="og:type" content="website">
|
|
||||||
<meta property="og:title" content="HNS Links">
|
|
||||||
<meta name="description" content="Create a links page for your domain">
|
<meta name="description" content="Create a links page for your domain">
|
||||||
<meta property="og:description" content="Create a links page for your domain">
|
|
||||||
<meta property="og:image" content="https://links.hns.au/assets/img/dashboard.png">
|
|
||||||
<meta name="twitter:description" content="Create a links page for your domain">
|
|
||||||
<script type="application/ld+json">
|
|
||||||
{
|
|
||||||
"@context": "http://schema.org",
|
|
||||||
"@type": "WebSite",
|
|
||||||
"name": "HNS Links",
|
|
||||||
"url": "https://links.hns.au"
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
|
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
|
||||||
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
|
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
|
||||||
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
|
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
|
||||||
|
@ -1,111 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html data-bs-theme="light" lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
|
||||||
<title>Nostr - HNS Links</title>
|
|
||||||
<meta name="twitter:title" content="HNS Links">
|
|
||||||
<meta name="twitter:image" content="https://links.hns.au/assets/img/dashboard.png">
|
|
||||||
<meta name="twitter:card" content="summary">
|
|
||||||
<meta property="og:type" content="website">
|
|
||||||
<meta property="og:title" content="HNS Links">
|
|
||||||
<meta name="description" content="Create a links page for your domain">
|
|
||||||
<meta property="og:description" content="Create a links page for your domain">
|
|
||||||
<meta property="og:image" content="https://links.hns.au/assets/img/dashboard.png">
|
|
||||||
<meta name="twitter:description" content="Create a links page for your domain">
|
|
||||||
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
|
|
||||||
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
|
|
||||||
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
|
|
||||||
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
|
|
||||||
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
|
|
||||||
<link rel="stylesheet" href="/assets/bootstrap/css/bootstrap.min.css">
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Inter:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800&display=swap">
|
|
||||||
<link rel="stylesheet" href="/assets/css/styles.min.css">
|
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
|
|
||||||
<script async src="https://umami.woodburn.au/script.js" data-website-id="a165bb1c-eef8-4737-8066-fcd8b4a380bd"></script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<nav class="navbar navbar-expand-md sticky-top py-3 navbar-dark" id="mainNav">
|
|
||||||
<div class="container"><a class="navbar-brand d-flex align-items-center" href="/"><img src="/assets/img/favicon.png" width="45px"><span> HNS Links</span></a><button data-bs-toggle="collapse" class="navbar-toggler" data-bs-target="#navcol-1"><span class="visually-hidden">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
|
|
||||||
<div class="collapse navbar-collapse" id="navcol-1">
|
|
||||||
<ul class="navbar-nav mx-auto"></ul><a class="btn btn-primary shadow" role="button" href="/preview" style="margin-right: 10px;">Preview</a><a class="btn btn-primary shadow" role="button" href="/logout">Logout</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
<header class="bg-dark">
|
|
||||||
<div class="container pt-4 pt-xl-5">
|
|
||||||
<div class="row pt-5">
|
|
||||||
<div class="col-md-8 col-xl-6 text-center text-md-start mx-auto">
|
|
||||||
<div class="text-center">
|
|
||||||
<p class="fw-bold text-success mb-2">{{domain}}/</p>
|
|
||||||
<h1 class="fw-bold">Manage your site</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
<section>
|
|
||||||
<div style="padding: 1em;padding-bottom: 25px;max-width: 800px;margin: auto;">
|
|
||||||
<form method="post" enctype="multipart/form-data">
|
|
||||||
<h1>Nostr</h1>
|
|
||||||
<div style="margin-bottom: 25px;">
|
|
||||||
<h4>Nostr Links</h4>{% for link in nostr %}
|
|
||||||
<div class='nostr'>
|
|
||||||
<input class="form-control" type="text" style="display: inline-block;width: auto;" value="{{link.name}}" readonly/>
|
|
||||||
<input class="form-control" type="text" style="display: inline-block;width: auto;" value="{{link.pub}}" readonly/>
|
|
||||||
<a class="btn btn-primary" role="button" href="/nostr/delete/{{link.id}}"><svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 24 24" width="1em" fill="currentColor">
|
|
||||||
<path d="M0 0h24v24H0z" fill="none"></path>
|
|
||||||
<path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"></path>
|
|
||||||
</svg></a>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
<div class='nostr'>
|
|
||||||
<span>Link a new nostr profile</span><br>
|
|
||||||
<input class="form-control" type="text" style="display: inline-block;width: auto;" name="new-name" placeholder="User Name" />
|
|
||||||
<input class="form-control" type="text" style="display: inline-block;width: auto;" name="new-pub" placeholder="npub..." />
|
|
||||||
<br><br>
|
|
||||||
<input class="btn btn-primary" type="submit" value="Link" style="margin-right: 20px;" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section></section>
|
|
||||||
<footer class="bg-dark">
|
|
||||||
<div class="container py-4 py-lg-5">
|
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-sm-4 col-md-3 text-center text-lg-start d-flex flex-column">
|
|
||||||
<h3 class="fs-6 fw-bold">Services</h3>
|
|
||||||
<ul class="list-unstyled">
|
|
||||||
<li><a href="https://hnshosting.au" target="_blank">Wordpress Hosting</a></li>
|
|
||||||
<li><a href="https://firewallet.au" target="_blank">FireWallet</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-4 col-md-3 text-center text-lg-start d-flex flex-column">
|
|
||||||
<h3 class="fs-6 fw-bold">About</h3>
|
|
||||||
<ul class="list-unstyled">
|
|
||||||
<li><a href="https://hns.au" target="_blank">HNSAU</a></li>
|
|
||||||
<li><a href="https://nathan.woodburn.au" target="_blank">Nathan.Woodburn/</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-3 text-center text-lg-start d-flex flex-column align-items-center order-first align-items-lg-start order-lg-last">
|
|
||||||
<div class="fw-bold d-flex align-items-center mb-2"><span>HNS Links</span></div>
|
|
||||||
<p class="text-muted">Easy to manage links page on Handshake domains</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<hr>
|
|
||||||
<div class="text-muted d-flex justify-content-between align-items-center pt-3">
|
|
||||||
<p class="mb-0">Copyright © {{year}} Nathan.Woodburn/</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
<script src="/assets/js/jquery.min.js"></script>
|
|
||||||
<script src="/assets/bootstrap/js/bootstrap.min.js"></script>
|
|
||||||
<script src="https://auth.varo.domains/v1"></script>
|
|
||||||
<script src="/assets/js/script.min.js"></script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@ -5,10 +5,6 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
||||||
<title>{{title}}</title>
|
<title>{{title}}</title>
|
||||||
<meta name="twitter:image" content="https://links.hns.au/assets/img/dashboard.png">
|
|
||||||
<meta name="twitter:card" content="summary">
|
|
||||||
<meta property="og:type" content="website">
|
|
||||||
<meta property="og:image" content="https://links.hns.au/assets/img/dashboard.png">
|
|
||||||
<meta name="twitter:title" content="{{title}}">
|
<meta name="twitter:title" content="{{title}}">
|
||||||
<meta property="og:title" content="{{title}}">
|
<meta property="og:title" content="{{title}}">
|
||||||
<meta name="description" content="{{title}}">
|
<meta name="description" content="{{title}}">
|
||||||
|
@ -5,10 +5,6 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
||||||
<title>{{title}}</title>
|
<title>{{title}}</title>
|
||||||
<meta name="twitter:image" content="https://links.hns.au/assets/img/dashboard.png">
|
|
||||||
<meta name="twitter:card" content="summary">
|
|
||||||
<meta property="og:type" content="website">
|
|
||||||
<meta property="og:image" content="https://links.hns.au/assets/img/dashboard.png">
|
|
||||||
<meta name="twitter:title" content="{{title}}">
|
<meta name="twitter:title" content="{{title}}">
|
||||||
<meta property="og:title" content="{{title}}">
|
<meta property="og:title" content="{{title}}">
|
||||||
<meta name="description" content="{{title}}">
|
<meta name="description" content="{{title}}">
|
||||||
|
@ -5,15 +5,7 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
||||||
<title>HNS Links</title>
|
<title>HNS Links</title>
|
||||||
<meta name="twitter:title" content="HNS Links">
|
|
||||||
<meta name="twitter:image" content="https://links.hns.au/assets/img/dashboard.png">
|
|
||||||
<meta name="twitter:card" content="summary">
|
|
||||||
<meta property="og:type" content="website">
|
|
||||||
<meta property="og:title" content="HNS Links">
|
|
||||||
<meta name="description" content="Create a links page for your domain">
|
<meta name="description" content="Create a links page for your domain">
|
||||||
<meta property="og:description" content="Create a links page for your domain">
|
|
||||||
<meta property="og:image" content="https://links.hns.au/assets/img/dashboard.png">
|
|
||||||
<meta name="twitter:description" content="Create a links page for your domain">
|
|
||||||
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
|
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
|
||||||
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
|
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
|
||||||
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
|
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
|
||||||
|
@ -5,15 +5,7 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
||||||
<title>Home - HNS Links</title>
|
<title>Home - HNS Links</title>
|
||||||
<meta name="twitter:title" content="HNS Links">
|
|
||||||
<meta name="twitter:image" content="https://links.hns.au/assets/img/dashboard.png">
|
|
||||||
<meta name="twitter:card" content="summary">
|
|
||||||
<meta property="og:type" content="website">
|
|
||||||
<meta property="og:title" content="HNS Links">
|
|
||||||
<meta name="description" content="Create a links page for your domain">
|
<meta name="description" content="Create a links page for your domain">
|
||||||
<meta property="og:description" content="Create a links page for your domain">
|
|
||||||
<meta property="og:image" content="https://links.hns.au/assets/img/dashboard.png">
|
|
||||||
<meta name="twitter:description" content="Create a links page for your domain">
|
|
||||||
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
|
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
|
||||||
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
|
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
|
||||||
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
|
<link rel="icon" type="image/png" sizes="600x627" href="/assets/img/favicon.png">
|
||||||
@ -96,7 +88,7 @@
|
|||||||
</div><input class="btn btn-primary" type="submit" value="Save" style="margin-right: 20px;"><a class="btn btn-primary" role="button" href="/publish">Publish</a>
|
</div><input class="btn btn-primary" type="submit" value="Save" style="margin-right: 20px;"><a class="btn btn-primary" role="button" href="/publish">Publish</a>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6" style="text-align: center;">{{preview|safe}}<a class="btn btn-primary" role="button" href="/nostr" style="margin-top: 1em;">Link Nostr</a></div>
|
<div class="col-md-6" style="text-align: center;">{{preview|safe}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user