refactor: dynamically generate website
Some checks failed
Build Docker images / docker (push) Failing after 13m58s
Some checks failed
Build Docker images / docker (push) Failing after 13m58s
This commit is contained in:
parent
5e9ed59e25
commit
56baffb242
13 changed files with 241 additions and 40 deletions
12
.editorconfig
Normal file
12
.editorconfig
Normal file
|
@ -0,0 +1,12 @@
|
|||
# EditorConfig is awesome: https://EditorConfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
2
.github/workflows/docker.yml
vendored
2
.github/workflows/docker.yml
vendored
|
@ -12,7 +12,7 @@ on:
|
|||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
IMAGE_NAME: "thedevminertv/ca-list"
|
||||
IMAGE_NAME: "thedevminertv/ca-cert-list"
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +0,0 @@
|
|||
*.override.yml
|
|
@ -1,4 +1,8 @@
|
|||
FROM ghcr.io/thedevminertv/gostatic:1.2.3
|
||||
FROM ghcr.io/thedevminertv/gostatic:1.2.5
|
||||
CMD ["-compress-level", "2"]
|
||||
|
||||
RUN apk add --no-cache openssl coreutils
|
||||
|
||||
COPY --chown=app:app ./entrypoint.sh /entrypoint.sh
|
||||
COPY --chown=app:app ./generate.sh /generate.sh
|
||||
COPY ./public /static
|
18
LICENSE
Normal file
18
LICENSE
Normal file
|
@ -0,0 +1,18 @@
|
|||
Copyright 2023 DevMiner <devminer@devminer.xyz>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the “Software”), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
35
README.md
Normal file
35
README.md
Normal file
|
@ -0,0 +1,35 @@
|
|||
# CA-Cert List
|
||||
|
||||
> This application provides a simple list to download your own root CA certificates. Useful for people that self-sign their own certificates.
|
||||
|
||||
![Screenshot](./_docs/Example-Page.png)
|
||||
|
||||
## Usage
|
||||
|
||||
Create your own Dockerfile which derives from `ghcr.io/thedevminertv/ca-cert-list:latest` and add your own certificates to `/certs`.
|
||||
The application will bind to port 80.
|
||||
|
||||
The application expects the `/certs` folder to contain the following files:
|
||||
|
||||
- `<Certificate name>` [Folder]
|
||||
- `cert.crt` [File]: Your certificate
|
||||
- `description.txt`: A description of your certificate
|
||||
|
||||
Example Dockerfile:
|
||||
|
||||
```dockerfile
|
||||
FROM ghcr.io/thedevminertv/ca-cert-list:latest
|
||||
|
||||
COPY ./certs /certs
|
||||
```
|
||||
|
||||
Build and run the container:
|
||||
|
||||
```bash
|
||||
docker build -t my-ca-cert-list .
|
||||
docker run -d -p 80:80 my-ca-cert-list
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License. See [LICENSE](./LICENSE) for more information.
|
BIN
_docs/Example-Page.png
Normal file
BIN
_docs/Example-Page.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 46 KiB |
10
compose.yml
10
compose.yml
|
@ -1,10 +0,0 @@
|
|||
version: '3'
|
||||
|
||||
services:
|
||||
certs:
|
||||
build: .
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.services.certs.loadbalancer.server.port=80"
|
||||
- "traefik.http.routers.certs.rule=Host(`certs.i.devminer.xyz`)"
|
||||
- "traefik.http.routers.certs.service=certs"
|
9
entrypoint.sh
Normal file
9
entrypoint.sh
Normal file
|
@ -0,0 +1,9 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
./generate.sh
|
||||
|
||||
chown -R app:app /static
|
||||
|
||||
su app -c "/bin/gostatic --files /static --addr :80 $*"
|
84
generate.sh
Normal file
84
generate.sh
Normal file
|
@ -0,0 +1,84 @@
|
|||
#!/bin/sh
|
||||
|
||||
mkdir -p /static/certificates
|
||||
|
||||
CERT_HTML=$(
|
||||
cat <<EOF
|
||||
<li>
|
||||
<a href="/certificates/{{FILENAME}}" download>
|
||||
<h2>{{NAME}}</h2>
|
||||
<span>{{DESCRIPTION}}</span>
|
||||
|
||||
<div class="chips">
|
||||
<div class="chip">
|
||||
<span>
|
||||
<span>Expiry</span>
|
||||
</span>
|
||||
<span class="local-date-time" data-timestamp="{{EXPIRY_TIMESTAMP}}">{{EXPIRY}}</span>
|
||||
</div>
|
||||
|
||||
<div class="chip">
|
||||
<span>
|
||||
<span>SHA256</span>
|
||||
</span>
|
||||
<span>
|
||||
<code>{{SHA256}}</code>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="chip">
|
||||
<span>
|
||||
<span>SHA1</span>
|
||||
</span>
|
||||
<span>
|
||||
<code>{{SHA1}}</code>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="chip">
|
||||
<span>
|
||||
<span>MD5</span>
|
||||
</span>
|
||||
<span>
|
||||
<code>{{MD5}}</code>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
EOF
|
||||
)
|
||||
|
||||
set -e
|
||||
|
||||
HTML=""
|
||||
for CERT in /certs/*; do
|
||||
file="$CERT/cert.crt"
|
||||
certname=$(basename "$CERT")
|
||||
|
||||
description=$(cat "$CERT/description.txt")
|
||||
expire_time=$(openssl x509 -enddate -noout -in "$file" | cut -d= -f2)
|
||||
expire_epoch=$(date -d "$expire_time" +%s)
|
||||
sha256=$(openssl x509 -in "$file" -noout -sha256 -fingerprint | cut -d= -f2)
|
||||
sha1=$(openssl x509 -in "$file" -noout -sha1 -fingerprint | cut -d= -f2)
|
||||
md5=$(openssl x509 -in "$file" -noout -md5 -fingerprint | cut -d= -f2)
|
||||
|
||||
component=$(
|
||||
echo $CERT_HTML |
|
||||
sed "s|{{NAME}}|$certname|g" |
|
||||
sed "s|{{FILENAME}}|${certname}.crt|g" |
|
||||
sed "s|{{DESCRIPTION}}|$description|g" |
|
||||
sed "s|{{EXPIRY_TIMESTAMP}}|$expire_epoch|g" |
|
||||
sed "s|{{EXPIRY}}|$expire_time|g" |
|
||||
sed "s|{{SHA256}}|$sha256|g" |
|
||||
sed "s|{{SHA1}}|$sha1|g" |
|
||||
sed "s|{{MD5}}|$md5|g"
|
||||
)
|
||||
|
||||
HTML="$HTML$component"
|
||||
|
||||
cp "$file" "/static/certificates/$certname.crt"
|
||||
done
|
||||
|
||||
# replace html
|
||||
sed -i "s|{{HTML}}|$HTML|g" /static/index.html
|
BIN
public/MonaspaceNeon-Light.otf
Normal file
BIN
public/MonaspaceNeon-Light.otf
Normal file
Binary file not shown.
BIN
public/MonaspaceNeon-Light.woff
Normal file
BIN
public/MonaspaceNeon-Light.woff
Normal file
Binary file not shown.
|
@ -6,6 +6,13 @@
|
|||
<title>Certificates / Zertifikate</title>
|
||||
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: "Monaspace Neon";
|
||||
src: url(/MonaspaceNeon-Light.woff) format("woff"),
|
||||
url(/MonaspaceNeon-Light.otf) format("opentype");
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
@ -27,8 +34,19 @@
|
|||
margin: 2rem;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: "Monaspace Neon", "Courier New", Courier, monospace;
|
||||
line-height: 1;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
span:has(code) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
body {
|
||||
max-width: 768px;
|
||||
max-width: 840px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
|
@ -38,13 +56,13 @@
|
|||
}
|
||||
|
||||
ul > li > a {
|
||||
padding: 1.25rem 1.25rem;
|
||||
padding: 1rem 1.25rem 1.25rem 1.25rem;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
|
||||
color: #ff00ff;
|
||||
color: #eee;
|
||||
text-decoration: none;
|
||||
|
||||
border: #272727 1px solid;
|
||||
|
@ -52,46 +70,78 @@
|
|||
|
||||
transition: border 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.chip {
|
||||
display: inline-block;
|
||||
|
||||
color: #eee;
|
||||
ul > li > a:hover {
|
||||
border: #ff00ff 1px solid;
|
||||
}
|
||||
|
||||
.chip > span:first-child {
|
||||
padding: 0.125rem 0.5rem;
|
||||
ul > li > a > :first-child {
|
||||
color: #ff00ff;
|
||||
|
||||
font-size: 1.25rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.chips {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.chip {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
color: #eee;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
overflow-wrap: anywhere;
|
||||
pointer-events: stroke;
|
||||
}
|
||||
|
||||
.chip > * {
|
||||
align-self: stretch;
|
||||
display: flex;
|
||||
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
|
||||
.chip > :first-child {
|
||||
min-width: fit-content;
|
||||
background-color: #353535;
|
||||
border-radius: 0.25rem 0 0 0.25rem;
|
||||
}
|
||||
|
||||
.chip > span:last-child {
|
||||
padding: 0.125rem 0.5rem;
|
||||
.chip > :first-child > * {
|
||||
margin: auto;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.chip > :last-child {
|
||||
line-height: 1;
|
||||
|
||||
background-color: #222222;
|
||||
border-radius: 0 0.25rem 0.25rem 0;
|
||||
}
|
||||
|
||||
ul > li > a:hover {
|
||||
border: #ff00ff 1px solid;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Certificates / Zertifikate</h1>
|
||||
<h1>Certificates</h1>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<a href="/certificates/root.crt" download>
|
||||
<span> Root CA / Wurzel-Zertifizierungsstelle </span>
|
||||
|
||||
<div class="chip">
|
||||
<span>Expiry date / Auslaufdatum</span><span>27.09.2033</span>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
{{HTML}}
|
||||
</ul>
|
||||
|
||||
<script>
|
||||
(() => {
|
||||
const els = document.querySelectorAll(".local-date-time");
|
||||
for (const el of els) {
|
||||
try {
|
||||
el.innerText = new Date(
|
||||
+el.dataset.timestamp * 1000
|
||||
).toLocaleDateString();
|
||||
} catch {}
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
Loading…
Reference in a new issue