feat: Add cli browser (lynx, w3m, etc.) as supported presentation

This commit is contained in:
Myzel394 2024-12-16 12:08:27 +01:00
parent fe33cec725
commit cab65cbefd
No known key found for this signature in database
GPG Key ID: ED20A1D1D423AF3F
13 changed files with 345 additions and 222 deletions

View File

@ -1,10 +1,12 @@
import { createMiddleware } from "hono/factory";
export type PresentationType = "terminal" | "browser";
export type PresentationType = "terminal" | "browser" | "cli-browser";
const TERMINAL_USER_AGENT =
/^(curl|wget|python-urllib|pycurl|java|go-http-client|php)/i;
const CLI_BROWSER_USER_AGENT = /^(lynx|elinks|w3m)/i;
const presentation = createMiddleware<{
Variables: {
presentation: PresentationType;
@ -14,6 +16,8 @@ const presentation = createMiddleware<{
if (TERMINAL_USER_AGENT.test(userAgent)) {
context.set("presentation", "terminal");
} else if (CLI_BROWSER_USER_AGENT.test(userAgent)) {
context.set("presentation", "cli-browser");
} else {
context.set("presentation", "browser");
}

View File

@ -6,6 +6,17 @@ import render from "../utils/renderer";
export const rootRoute = new Hono();
rootRoute.get("/", realIP, presentation, context => {
// Move request to correct route
const { port, ipAddress } = context.req.query();
if (port) {
if (ipAddress) {
return context.redirect(`/${ipAddress}/${port}`);
} else {
return context.redirect(`/${port}`);
}
}
return render(context, "index", {
ip: context.get("ip"),
});

View File

@ -11,14 +11,17 @@ export default async function render(
const extension = {
browser: ".html",
terminal: ".txt",
"cli-browser": ".cli.html",
}[presentation];
const key = templateName + extension + ".njk";
const key = templateName + ".njk" + extension;
const content = nunjucks.render(key, ctx);
switch (presentation) {
case "browser":
return context.html(content);
case "cli-browser":
return context.html(content);
case "terminal":
return context.text(content.trimEnd());
}

View File

@ -0,0 +1,40 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>amiopen.now</title>
{% block header %}{% endblock %}
</head>
<body>
<main>
{% block main %}
<h2>Am I Open</h2>
{% endblock %}
<br />
<br />
<a href="/">To root /</a>
<br />
<ul>
<a
href="https://github.com/Myzel394/amiopen.now"
target="_blank"
rel="noopener noreferrer"
>
<img src="/static/github.svg" alt="GitHub" />
</a>
<a
href="https://twitter.com/Myzel394"
target="_blank"
rel="noopener noreferrer"
>
<img src="/static/twitter.svg" alt="Twitter / X" />
</a>
</ul>
</main>
<i>No logs are stored. I have no idea that you were here.</i>
</body>
</html>

View File

@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="darkreader-lock">
<meta name="darkreader-lock" />
<title>amiopen.now</title>
<style type="text/css">
@ -70,20 +70,27 @@
<body>
<main>
{% block main %}
<h2>Am I Open</h2>
<h2>Am I Open</h2>
{% endblock %}
<div class="socials">
<a href="https://github.com/Myzel394/amiopen.now" target="_blank" rel="noopener noreferrer">
<a
href="https://github.com/Myzel394/amiopen.now"
target="_blank"
rel="noopener noreferrer"
>
<img src="/static/github.svg" alt="GitHub" />
</a>
<a href="https://twitter.com/Myzel394" target="_blank" rel="noopener noreferrer">
<a
href="https://twitter.com/Myzel394"
target="_blank"
rel="noopener noreferrer"
>
<img src="/static/twitter.svg" alt="Twitter / X" />
</a>
</div>
</main>
<i id="hint">No logs are stored. I have no idea that you were here.</i>
{% block scripts %}
{% endblock %}
{% block scripts %} {% endblock %}
</body>
</html>

View File

@ -1,118 +0,0 @@
{% extends "base.html.njk" %}
{% block header %}
<style type="text/css">
code {
background-color: #2f2f2f;
color: #eee;
padding: 1em;
border-radius: 0.5em;
width: 100%;
display: block;
}
code .command {
color: #598eb2;
}
code .input {
color: #b27b59;
}
code .second-input {
color: #b2596e;
}
code .secondary {
color: #b2a559;
}
code .comment {
color: #5c6370;
}
code a {
text-decoration: none;
text-underline-offset: .15em;
color: unset;
}
code a:hover {
text-decoration: underline dotted 1px #aaa;
}
.copy {
cursor: pointer;
border: none;
border-radius: 0.4em;
aspect-ratio: 1;
background: transparent;
vertical-align: middle;
transition: background-color 0.2s;
}
.copy:hover {
background: #ffffff40;
}
.copy img {
width: 1rem;
color: #fff;
filter: invert(1);
}
</style>
{% endblock %}
{% block main %}
<h2>Am I Open</h2>
<small>
A small, terminal-friendly utility for checking your ports and your IP address.
</small>
<p>
Your IP address: <strong>{{ip}}</strong>
<button class="copy" id="copy-ip">
<img width="1em" src="/static/copy.svg" alt="Copy" />
</button>
</p>
<strong> Check if your port is reachable: </strong>
<pre><code><span class="comment">$</span> <span class="command">curl</span> amiopen.now/<span class="input">&lt;port&gt;</span>
<span class="comment">// Example</span>
<span class="comment">$</span> <a href="/80"><span class="command">curl</span> amiopen.now/<span class="input">80</span></a>
> open</code></pre>
<strong> Check if an IP address is reachable: </strong>
<pre><code><span class="comment">$</span> <span class="command">curl</span> amiopen.now/<span class="second-input">&lt;ip address&gt;</span>/<span class="input">&lt;port&gt;</span>
<span class="comment">// Example</span>
<span class="comment">$</span> <a href="/1.1.1.1/53"><span class="command">curl</span> amiopen.now/<span class="second-input">1.1.1.1</span>/<span class="input">53</span></a>
> open</code></pre>
<strong> Check if your ISP is blocking a port: </strong>
<pre><code><span class="comment">$</span> <span class="command">telnet</span> amiopen.now <span class="input">&lt;port&gt;</span>
<span class="comment">// Example</span>
<span class="comment">$</span> <span class="command">telnet</span> amiopen.now <span class="input">80</span></code></pre>
<i>
Hint: You can also check if you can access SSH by using:
<pre><code><span class="comment">$</span> <span class="command">ssh</span> <span class="secondary">hello</span>@amiopen.now</code></pre>
</i>
{% endblock %}
{% block scripts %}
<script defer>
const $copyButton = document.getElementById("copy-ip");
const ip = "{{ip}}";
$copyButton.addEventListener("click", () => {
navigator.clipboard.writeText(ip);
});
</script>
{% endblock %}

View File

@ -0,0 +1,58 @@
{% extends "base.njk.cli.html" %} {% block main %}
<h2>Am I Open</h2>
<small>
A small, terminal-friendly utility for checking your ports and your IP
address.
</small>
<p>Your IP address: <strong>{{ip}}</strong></p>
<strong>Check if your port is reachable:</strong>
<br />
amiopen.now/<i>&lt;port&gt;</i>
<br />
<br />
<strong>Example:</strong>
<br />
<a href="/80">amiopen.now/<i>80</i></a>
<br />
<br />
<form action="/" method="get">
amiopen.now/<input type="text" name="port" />
<button type="submit">Check</button>
</form>
<br />
<br />
<hr />
<br />
<br />
<strong>Check if an IP address is reachable:</strong>
<br />
amiopen.now/<i>&lt;ip address&gt;</i>/<i>&lt;port&gt;</i>
<br />
<br />
<strong>Example:</strong>
<br />
<a href="/1.1.1.1/53">amiopen.now/<i>1.1.1.1</i>/<i>53</i></a>
<br />
<br />
<form action="/" method="get">
amiopen.now/<input type="text" name="ipAddress" />/<input
type="text"
name="port"
/>
<button type="submit">Check</button>
</form>
{% endblock %}

113
templates/index.njk.html Normal file
View File

@ -0,0 +1,113 @@
{% extends "base.njk.html" %} {% block header %}
<style type="text/css">
code {
background-color: #2f2f2f;
color: #eee;
padding: 1em;
border-radius: 0.5em;
width: 100%;
display: block;
}
code .command {
color: #598eb2;
}
code .input {
color: #b27b59;
}
code .second-input {
color: #b2596e;
}
code .secondary {
color: #b2a559;
}
code .comment {
color: #5c6370;
}
code a {
text-decoration: none;
text-underline-offset: 0.15em;
color: unset;
}
code a:hover {
text-decoration: underline dotted 1px #aaa;
}
.copy {
cursor: pointer;
border: none;
border-radius: 0.4em;
aspect-ratio: 1;
background: transparent;
vertical-align: middle;
transition: background-color 0.2s;
}
.copy:hover {
background: #ffffff40;
}
.copy img {
width: 1rem;
color: #fff;
filter: invert(1);
}
</style>
{% endblock %} {% block main %}
<h2>Am I Open</h2>
<small>
A small, terminal-friendly utility for checking your ports and your IP
address.
</small>
<p>
Your IP address: <strong>{{ip}}</strong>
<button class="copy" id="copy-ip">
<img width="1em" src="/static/copy.svg" alt="Copy" />
</button>
</p>
<strong> Check if your port is reachable: </strong>
<pre><code><span class="comment">$</span> <span class="command">curl</span> amiopen.now/<span class="input">&lt;port&gt;</span>
<span class="comment">// Example</span>
<span class="comment">$</span> <a href="/80"><span class="command">curl</span> amiopen.now/<span class="input">80</span></a>
> open</code></pre>
<strong> Check if an IP address is reachable: </strong>
<pre><code><span class="comment">$</span> <span class="command">curl</span> amiopen.now/<span class="second-input">&lt;ip address&gt;</span>/<span class="input">&lt;port&gt;</span>
<span class="comment">// Example</span>
<span class="comment">$</span> <a href="/1.1.1.1/53"><span class="command">curl</span> amiopen.now/<span class="second-input">1.1.1.1</span>/<span class="input">53</span></a>
> open</code></pre>
<strong> Check if your ISP is blocking a port: </strong>
<pre><code><span class="comment">$</span> <span class="command">telnet</span> amiopen.now <span class="input">&lt;port&gt;</span>
<span class="comment">// Example</span>
<span class="comment">$</span> <span class="command">telnet</span> amiopen.now <span class="input">80</span></code></pre>
<i>
Hint: You can also check if you can access SSH by using:
<pre><code><span class="comment">$</span> <span class="command">ssh</span> <span class="secondary">hello</span>@amiopen.now</code></pre>
</i>
{% endblock %} {% block scripts %}
<script defer>
const $copyButton = document.getElementById("copy-ip");
const ip = "{{ip}}";
$copyButton.addEventListener("click", () => {
navigator.clipboard.writeText(ip);
});
</script>
{% endblock %}

View File

@ -1,96 +0,0 @@
{% extends "base.html.njk" %}
{% block header %}
<style type="text/css">
.status {
display: flex;
align-items: center;
justify-content: center;
text-align: center;
column-gap: .6em;
font-size: 1.5rem;
}
.status p {
margin: 0;
font-weight: bold;
font-size: 1.2em;
}
#icon {
width: 0.7em;
height: 0.7em;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
.status.success {
color: #2ecc71;
}
.status.error {
color: #e74c3c;
}
.status.success #icon {
background-color: #2ecc71;
}
.status.error #icon {
background-color: #e74c3c;
}
.status.success #icon::before {
content: "";
width: 100%;
height: 100%;
border-radius: 50%;
background-color: #2ecc71;
opacity: 0.3;
position: absolute;
top: 0;
left: 0;
transform: scale(2);
animation: pulse 3s ease-out infinite;
}
@keyframes pulse {
0% {
transform: scale(1);
opacity: 0.6;
}
100% {
transform: scale(2);
opacity: 0;
}
}
</style>
{% endblock %}
{% block main %}
<h2>Am I Open</h2>
<i>{{ ip }}</i>
{% if isOpen %}
<div class="status success">
<div id="icon"></div>
<p>Port <strong>{{port}}</strong> is open</p>
</div>
{% else %}
<div class="status error">
<div id="icon"></div>
<p>Port <strong>{{port}}</strong> is closed</p>
</div>
{% endif %}
{% endblock %}

View File

@ -0,0 +1,10 @@
{% extends "base.njk.cli.html" %} {% block main %}
<h2>Am I Open</h2>
<i>{{ ip }}</i>
{% if isOpen %}
<p>Port <strong>{{port}}</strong> is <i>open</i></p>
{% else %}
<p>Port <strong>{{port}}</strong> is <i>closed</i></p>
{% endif %} {% endblock %}

91
templates/port.njk.html Normal file
View File

@ -0,0 +1,91 @@
{% extends "base.njk.html" %} {% block header %}
<style type="text/css">
.status {
display: flex;
align-items: center;
justify-content: center;
text-align: center;
column-gap: 0.6em;
font-size: 1.5rem;
}
.status p {
margin: 0;
font-weight: bold;
font-size: 1.2em;
}
#icon {
width: 0.7em;
height: 0.7em;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
.status.success {
color: #2ecc71;
}
.status.error {
color: #e74c3c;
}
.status.success #icon {
background-color: #2ecc71;
}
.status.error #icon {
background-color: #e74c3c;
}
.status.success #icon::before {
content: "";
width: 100%;
height: 100%;
border-radius: 50%;
background-color: #2ecc71;
opacity: 0.3;
position: absolute;
top: 0;
left: 0;
transform: scale(2);
animation: pulse 3s ease-out infinite;
}
@keyframes pulse {
0% {
transform: scale(1);
opacity: 0.6;
}
100% {
transform: scale(2);
opacity: 0;
}
}
</style>
{% endblock %} {% block main %}
<h2>Am I Open</h2>
<i>{{ ip }}</i>
{% if isOpen %}
<div class="status success">
<div id="icon"></div>
<p>Port <strong>{{port}}</strong> is open</p>
</div>
{% else %}
<div class="status error">
<div id="icon"></div>
<p>Port <strong>{{port}}</strong> is closed</p>
</div>
{% endif %} {% endblock %}