v1
141
README.md
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
# [stilde][stilde_repo]
|
||||||
|
|
||||||
|
![Bash](https://img.shields.io/badge/bash-1f425f.svg?style=for-the-badge&logo=image%2Fpng%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw%2FeHBhY2tldCBiZWdpbj0i77u%2FIiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8%2BIDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNSwgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkE3MDg2QTAyQUZCMzExRTVBMkQxRDMzMkJDMUQ4RDk3IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkE3MDg2QTAzQUZCMzExRTVBMkQxRDMzMkJDMUQ4RDk3Ij4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6QTcwODZBMDBBRkIzMTFFNUEyRDFEMzMyQkMxRDhEOTciIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6QTcwODZBMDFBRkIzMTFFNUEyRDFEMzMyQkMxRDhEOTciLz4gPC9yZGY6RGVzY3JpcHRpb24%2BIDwvcmRmOlJERj4gPC94OnhtcG1ldGE%2BIDw%2FeHBhY2tldCBlbmQ9InIiPz6lm45hAAADkklEQVR42qyVa0yTVxzGn7d9Wy03MS2ii8s%2BeokYNQSVhCzOjXZOFNF4jx%2BMRmPUMEUEqVG36jo2thizLSQSMd4N8ZoQ8RKjJtooaCpK6ZoCtRXKpRempbTv5ey83bhkAUphz8fznvP8znn%2B%2F3NeEEJgNBoRRSmz0ub%2FfuxEacBg%2FDmYtiCjgo5NG2mBXq%2BH5I1ogMRk9Zbd%2BQU2e1ML6VPLOyf5tvBQ8yT1lG10imxsABm7SLs898GTpyYynEzP60hO3trHDKvMigUwdeaceacqzp7nOI4n0SSIIjl36ao4Z356OV07fSQAk6xJ3XGg%2BLCr1d1OYlVHp4eUHPnerU79ZA%2F1kuv1JQMAg%2BE4O2P23EumF3VkvHprsZKMzKwbRUXFEyTvSIEmTVbrysp%2BWr8wfQHGK6WChVa3bKUmdWou%2BjpArdGkzZ41c1zG%2Fu5uGH4swzd561F%2BuhIT4%2BLnSuPsv9%2BJKIpjNr9dXYOyk7%2FBZrcjIT4eCnoKgedJP4BEqhG77E3NKP31FO7cfQA5K0dSYuLgz2TwCWJSOBzG6crzKK%2BohNfni%2Bx6OMUMMNe%2Fgf7ocbw0v0acKg6J8Ql0q%2BT%2FAXR5PNi5dz9c71upuQqCKFAD%2BYhrZLEAmpodaHO3Qy6TI3NhBpbrshGtOWKOSMYwYGQM8nJzoFJNxP2HjyIQho4PewK6hBktoDcUwtIln4PjOWzflQ%2Be5yl0yCCYgYikTclGlxadio%2BBQCSiW1UXoVGrKYwH4RgMrjU1HAB4vR6LzWYfFUCKxfS8Ftk5qxHoCUQAUkRJaSEokkV6Y%2F%2BJUOC4hn6A39NVXVBYeNP8piH6HeA4fPbpdBQV5KOx0QaL1YppX3Jgk0TwH2Vg6S3u%2BdB91%2B%2FpuNYPYFl5uP5V7ZqvsrX7jxqMXR6ff3gCQSTzFI0a1TX3wIs8ul%2Bq4HuWAAiM39vhOuR1O1fQ2gT%2F26Z8Z5vrl2OHi9OXZn995nLV9aFfS6UC9JeJPfuK0NBohWpCHMSAAsFe74WWP%2BvT25wtP9Bpob6uGqqyDnOtaeumjRu%2ByFu36VntK%2FPA5umTJeUtPWZSU9BCgud661odVp3DZtkc7AnYR33RRC708PrVi1larW7XwZIjLnd7R6SgSqWSNjU1B3F72pz5TZbXmX5vV81Yb7Lg7XT%2FUXriu8XLVqw6c6XqWnBKiiYU%2BMt3wWF7u7i91XlSEITwSAZ%2FCzAAHsJVbwXYFFEAAAAASUVORK5CYII%3D)
|
||||||
|
https://img.shields.io/badge/staticrypt-v3.3.0-brightgreen
|
||||||
|
|
||||||
|
**stilde** is the template for my personal startpage.
|
||||||
|
|
||||||
|
The startpage by itself is a lightly modified version of the **[tilde][tilde_repo]** project by [cade](https://github.com/xvvvyz).
|
||||||
|
|
||||||
|
I use it both locally (localhost file) and self-hosted (https), that's why I wanted a way to protect the page that would still stay light, static and bypassable by an action-less uri.
|
||||||
|
|
||||||
|
Stilde include **[staticrypt][staticrypt_repo]** for that purpose and provide an authentification form to decrypt the page locally by password or by a decryption uri without any other input.
|
||||||
|
|
||||||
|
[Staticrypt Form](assets/screenshots/startpage.png)
|
||||||
|
[Stilde Startpage](assets/screenshots/staticrypt.png)
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- All tilde features.
|
||||||
|
- Redirect to a bookmarked website.
|
||||||
|
- Run a search on a bookmarked website.
|
||||||
|
- Get search suggestions from DuckDuckGo.
|
||||||
|
- Redirect to a specific path or uri for a bookmarked website.
|
||||||
|
- Access any other url.
|
||||||
|
- Lauch a search on a customized DuckDuckGo session for anything outside the scope.
|
||||||
|
- WebCrypto html encryption with password prompt.
|
||||||
|
- Direct decryption by secret hash uri.
|
||||||
|
- Deployment and re-deployment with one command.
|
||||||
|
- New: custom logo on both form and startpage.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
UNLICENCED : like the original tilde project.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- npm@lts (I use v18.16.0 with nvm)
|
||||||
|
- Bash (for the `build.sh` script)
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
- Clone this repo in a parent directory outside of your webroot (the webroot is the destination of the build):
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
git clone --depth=1 https://git.tkapias.net/tkapias/stilde
|
||||||
|
cd stilde
|
||||||
|
```
|
||||||
|
|
||||||
|
## Preparation (optional)
|
||||||
|
|
||||||
|
- Edit french strings for the staticrypt form in `build.sh`:
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
85 │ --template-button "DECRYPTER" \
|
||||||
|
86 │ --template-instructions "Crypté avec StatiCrypt." \
|
||||||
|
87 │ --template-error "Mot de passe incorrect !" \
|
||||||
|
88 │ --template-placeholder "Mot de passe" \
|
||||||
|
89 │ --template-remember "Se souvenir de moi" \
|
||||||
|
```
|
||||||
|
|
||||||
|
- Edit graphical asset in `assets/root/`:
|
||||||
|
- favicon.ico (`convert icon-512.png -define icon:auto-resize="48,32,16" favicon.ico`)
|
||||||
|
- favicon.svg (square logo, width 192px)
|
||||||
|
- icon-192.png (generated from favicon.svg)
|
||||||
|
- icon-512.png (generated from favicon.svg)
|
||||||
|
- logo.svg (trimmed favicon.svg, width 200px)
|
||||||
|
|
||||||
|
- Replace the svg logo in the startpage `assets/source/index.html`:
|
||||||
|
|
||||||
|
I exported mines from inkscape, cleaned it's code and renamed paths to use them in css and scripts.
|
||||||
|
|
||||||
|
``` html
|
||||||
|
622 │ <div class="box-container">
|
||||||
|
623 │
|
||||||
|
624 │ <svg
|
||||||
|
625 │ preserveAspectRatio=true
|
||||||
|
656 | ...
|
||||||
|
```
|
||||||
|
|
||||||
|
There are also some css rules for the logo paths:
|
||||||
|
|
||||||
|
``` css
|
||||||
|
607 │ #logo path#characters {
|
||||||
|
608 │ fill-opacity: 0.5 !important;
|
||||||
|
609 │ transition: fill 2s, fill-opacity 1s;
|
||||||
|
610 │ }
|
||||||
|
611 │ #logo path#characters:hover {
|
||||||
|
612 │ fill: #ff4000 !important;
|
||||||
|
613 │ fill-opacity: 0.8 !important;
|
||||||
|
614 │ transition: fill 2s, fill-opacity 1s;
|
||||||
|
615 │ }
|
||||||
|
616 │ #logo path#shadows {
|
||||||
|
617 │ fill: #808080;
|
||||||
|
618 │ transition: fill 2s;
|
||||||
|
619 │ }
|
||||||
|
```
|
||||||
|
|
||||||
|
And some javascript too:
|
||||||
|
|
||||||
|
``` javascript
|
||||||
|
339 │ const shadows = document.querySelector('#logo path#shadows');
|
||||||
|
438 │ shadows.style.fill = '#808080'
|
||||||
|
465 │ shadows.style.fill = '#ff4000'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Bookmarks & Commands
|
||||||
|
|
||||||
|
All of them are included inside the `COMMANDS` const after line 41 of `assets/source/index.html`.
|
||||||
|
|
||||||
|
I left enough examples to understand the syntax.
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
Just execute `build.sh` with its help:
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
Generate static website with encrypted code by staticrypt.
|
||||||
|
The first pass requires -t, -d and -u options, re-run it with -c option only.
|
||||||
|
|
||||||
|
Syntax: ./build.sh [-h] [Options...]
|
||||||
|
|
||||||
|
options:
|
||||||
|
-h Print this Help
|
||||||
|
-c Fetch options from ".staticrypt.conf"
|
||||||
|
-d "<path>" Desination webroot path or directory
|
||||||
|
-p "<password>" Password for decryption >= 12 characters
|
||||||
|
-s "<salt>" Salt string = 32 hexadecimal characters
|
||||||
|
-t "<string>" Title for the staticrypt form page
|
||||||
|
-u "<url>" Https or localhost Url for the destination root
|
||||||
|
|
||||||
|
Example: ./build.sh -u https://start.domain.tld -d static -t "STILDE - StartPage"
|
||||||
|
```
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
[//]: # (LINKS)
|
||||||
|
[stilde_repo]: https://git.tkapias.net/tkapias/stilde
|
||||||
|
[tilde_repo]: https://github.com/xvvvyz/tilde
|
||||||
|
[staticrypt_repo]: https://github.com/robinmoisson/staticrypt
|
BIN
assets/root/favicon.ico
Normal file
After Width: | Height: | Size: 15 KiB |
83
assets/root/favicon.svg
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="56.917mm"
|
||||||
|
height="56.917004mm"
|
||||||
|
viewBox="-1 -13.22 56.918076 56.918082"
|
||||||
|
version="1.1"
|
||||||
|
id="svg8"
|
||||||
|
inkscape:version="1.0.2 (e86c870879, 2021-01-15)"
|
||||||
|
sodipodi:docname="INKSCAPE_Logo_TKA.svg"
|
||||||
|
inkscape:export-filename="logo.svg"
|
||||||
|
inkscape:export-xdpi="96.001877"
|
||||||
|
inkscape:export-ydpi="96.001877"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||||
|
<g
|
||||||
|
aria-label=" ████████╗██╗ ██╗ █████╗ ╚══██╔══╝██║ ██╔╝██╔══██╗ ██║ █████╔╝ ███████║ ██║ ██╔═██╗ ██╔══██║ ██║ ██║ ██╗██║ ██║ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝"
|
||||||
|
id="text833-8"
|
||||||
|
style="font-size:10.5833px;line-height:1.25;font-family:'Copperplate Gothic Bold';-inkscape-font-specification:'Copperplate Gothic Bold, ';white-space:pre;shape-inside:url(#rect835);display:inline"
|
||||||
|
inkscape:label="TKA Blanc"
|
||||||
|
transform="matrix(0.57142858,0,0,0.57142858,-0.93067806,-68.229932)">
|
||||||
|
<path
|
||||||
|
id="path1748"
|
||||||
|
style="color:#000000;font-size:10.5833px;line-height:1.25;font-family:'Copperplate Gothic Bold';-inkscape-font-specification:'Noto Sans Mono';white-space:pre;shape-inside:url(#rect835);display:inline;fill:#808080;fill-opacity:0.503856;stroke:none;stroke-width:0.401402;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
|
||||||
|
d="m 206.65832,477.40693 v 4.35548 h 12.42184 v 34.65225 25.84255 H 205.95563 181.954 157.95237 147.04042 v 32.72422 h 0.0348 v 57.05107 57.81182 l 0.0465,57.05687 h -0.0465 v 26.5975 h -13.11873 -0.48201 -23.51962 -13.600734 v -33.94956 h -4.355487 v 38.29924 h 17.956221 23.51962 0.48201 17.47421 v -29.43728 h 0.0406 l -0.0406,-58.56677 V 632.0325 573.47153 h -0.0406 v -26.86464 h 6.56227 24.00163 24.00163 17.47421 v -30.19223 -39.00773 z m 71.99909,0 v 4.35548 h 12.42185 v 34.65225 57.10333 h 4.34968 v -57.10333 -39.00773 z m 120.00236,0 v 4.35548 h 12.41604 v 34.65225 25.84255 h -13.12453 -10.91776 l 0.0465,31.96927 v 25.84255 H 373.95545 363.0377 v 31.26078 h 4.34968 v -26.9111 h 6.56807 17.47421 v -30.19223 l -0.0407,-27.61959 h 6.56227 17.48001 v -30.19223 -39.00773 z m 167.99982,0 v 4.35548 h 12.41603 v 33.94376 h 4.34968 v -38.29924 z m -360.00127,7.03846 v 4.35549 h 5.38338 v 27.61378 18.80409 H 205.95563 181.954 157.95237 139.99615 v 39.00773 57.80602 57.81182 l 0.0406,57.81182 v 18.80409 h -6.08026 -0.48201 -23.51962 -6.56227 v -26.9111 h -4.355485 v 31.26077 h 10.917755 23.51962 0.48201 10.43575 v -23.15376 l -0.0407,-57.81182 V 632.0325 574.22648 539.56843 h 13.60074 24.00163 24.00163 10.43575 v -23.15377 -31.96927 z m 71.99909,0 v 4.35549 h 5.38338 v 26.85883 h -0.0407 v 57.85828 h 4.34968 v -56.34838 h 0.0406 v -32.72422 z m 120.00236,0 v 4.35549 h 5.37757 v 27.61378 18.80409 h -6.08606 -17.95042 l 0.0349,39.00773 v 18.79828 h -6.08026 -17.95622 v 38.30505 h 4.34968 v -33.94956 h 13.60654 10.43575 v -23.15377 l -0.0407,-34.65805 h 13.60074 10.43574 v -23.15377 -31.96927 z m 167.99982,0 v 4.35549 h 5.37757 v 26.90529 h 4.34968 V 484.44539 Z M 19.999597,508.30765 v 38.29924 h 17.956219 24.001633 22.811133 v -4.34968 H 61.957449 37.955816 24.349276 v -33.94956 z m 7.038466,0 v 31.26078 h 10.917753 24.001633 22.811133 v -4.34968 H 61.957449 37.955816 31.387742 v -26.9111 z m 448.957717,26.9111 v 0.75495 37.54429 h 4.35549 v -33.94956 h 13.60073 24.00163 22.81114 v -4.34968 H 517.95363 493.952 Z m 114.65963,0 v 4.34968 h 12.42185 v 34.65805 57.80602 57.81182 57.81182 25.84255 h -13.12453 -0.48201 -23.51963 -13.60073 v -33.94956 h -4.35549 v 38.29924 h 17.95622 23.51963 0.48201 17.47421 V 747.65614 689.84432 632.0325 574.22648 535.21875 Z m -107.62116,7.03846 v 0.75495 30.50583 h 4.35548 v -26.9111 h 6.56227 24.00163 22.81114 v -4.34968 H 517.95363 493.952 Z m 107.62116,0 v 4.34968 h 5.38338 v 26.86464 h -0.0406 v 58.56097 57.81182 58.56677 h 0.0406 v 18.04914 h -6.08606 -0.48201 -23.51963 -6.56226 v -26.9111 h -4.34968 v 31.26077 h 10.91194 23.51963 0.48201 10.43574 v -23.90871 h -0.0407 V 689.84432 632.0325 574.98143 h 0.0407 V 542.25721 Z M 284.00014,650.83658 v 0.75495 38.25279 l 0.0407,57.81182 v 18.80409 h -6.08607 -24.00163 -6.56226 v -26.9111 h -4.34968 v 31.26077 h 10.91194 24.00163 10.43575 v -23.15376 l -0.0406,-57.81182 v -34.65225 h 13.60073 22.81694 v -4.35549 h -22.81694 z m 90.658,0 v 4.35549 h 12.42184 v 33.94376 h 4.34968 v -38.29925 z m 101.33764,0 v 0.75495 38.25279 l 0.0406,57.81182 v 18.80409 h -6.08606 -23.99583 -6.56807 v -26.9111 h -4.34968 v 31.26077 h 10.91775 23.99583 10.43574 v -23.15376 l -0.0348,-57.81182 v -34.65225 h 13.60073 24.00163 22.81114 v -4.35549 H 517.95363 493.952 Z m -184.95717,7.04428 v 0.75495 31.96346 h 0.0406 l 0.0407,56.30192 h -0.0407 v 26.5975 h -13.12454 -24.00163 -13.60073 v -33.94956 h -4.35549 v 38.29924 h 17.95622 24.00163 17.47422 v -29.43728 h 0.0406 l -0.0406,-59.32172 h -0.0407 v -26.85884 h 6.56227 22.81694 v -4.34967 h -22.81694 z m 83.61953,0 v 4.34967 h 5.37757 v 26.9053 h 4.35549 v -31.25497 z m 108.37611,0 v 0.75495 31.96346 h 0.0407 l 0.0406,56.30192 h -0.0406 v 26.5975 H 469.95037 445.95454 432.348 v -33.94956 h -4.34968 v 38.29924 h 17.95622 23.99583 17.48002 v -29.43728 h 0.0407 l -0.0407,-59.32172 h -0.0407 v -26.85884 h 6.56227 24.00163 22.81114 v -4.34967 H 517.95363 493.952 Z M 331.9976,681.73731 v 38.29924 h 16.77152 v -4.34968 h -12.42184 v -33.94956 z m 7.03846,0 v 31.26077 h 9.73306 v -4.34968 h -5.37757 v -26.91109 z m 59.62371,26.91109 v 4.34968 h 12.41604 v 34.65806 25.84255 h -13.12453 -23.99583 -13.60654 v -33.94956 h -4.34968 v 38.29924 h 17.95622 23.99583 17.48001 V 747.65614 708.6484 Z m 0,7.03847 v 4.34968 h 5.37757 v 27.61959 18.80409 h -6.08606 -23.99583 -6.56807 v -26.9111 h -4.34968 v 31.26077 h 10.91775 23.99583 10.43574 v -23.15376 -31.96927 z"
|
||||||
|
transform="matrix(0.15572681,0,0,0.15572681,1.390094,49.845283)" />
|
||||||
|
<path
|
||||||
|
id="path1774"
|
||||||
|
style="color:#000000;font-size:10.5833px;line-height:1.25;font-family:'Copperplate Gothic Bold';-inkscape-font-specification:'Noto Sans Mono';white-space:pre;shape-inside:url(#rect835);display:inline;fill:#9e9e9e;fill-opacity:1;stroke:none;stroke-width:1.88976;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:none"
|
||||||
|
d="m 12.76949,457.90016 v 0.94078 49.46671 h 24.948225 23.995826 24.001633 24.001636 23.99582 24.00164 24.00163 24.94242 V 457.90016 H 181.7159 157.71427 133.71263 109.71681 85.715174 61.713541 37.717715 Z m 215.99728,0 v 0.94078 49.46671 h 24.94822 24.94242 v -50.40749 h -24.94242 z m 120.00235,0 v 0.94078 49.46671 h 24.94242 24.94823 v -50.40749 h -24.94823 z m 96.00073,0 v 0.94078 49.46671 h 24.94242 24.00163 24.00163 23.99583 24.94822 V 457.90016 H 541.71136 517.71553 493.7139 469.71227 Z M 84.768582,515.70617 v 0.9466 49.4667 h 24.948228 24.94242 v -50.4133 h -24.94242 z m 143.998188,0 v 0.9466 49.4667 h 24.94822 24.94242 v -50.4133 h -24.94242 z m 96.00072,0 v 0.9466 49.4667 h 24.94823 24.94241 v -50.4133 h -24.94241 z m 96.00072,0 v 0.9466 49.4667 h 24.94242 24.94823 v -50.4133 h -24.94823 z m 119.99656,0 v 0.9466 49.4667 h 24.94822 24.94242 v -50.4133 H 565.71299 Z M 84.768582,573.51799 v 0.9466 49.46671 h 24.948228 24.94242 v -50.41331 h -24.94242 z m 143.998188,0 v 0.9466 49.46671 h 24.94822 24.00163 23.99583 24.00163 24.94242 v -50.41331 h -24.94242 -24.00163 -23.99583 -24.00163 z m 192.00144,0 v 0.9466 49.46671 h 24.94242 24.00164 24.00163 24.00163 23.99583 24.00163 24.94242 V 573.51799 H 565.71299 541.71136 517.71553 493.7139 469.71227 445.71063 Z M 84.768582,631.32982 v 0.94078 49.46671 h 24.948228 24.94242 v -50.40749 h -24.94242 z m 143.998188,0 v 0.94078 49.46671 h 24.94822 24.94242 v -50.40749 h -24.94242 z m 96.00072,0 v 0.94078 49.46671 h 24.94823 24.94241 v -50.40749 h -24.94241 z m 96.00072,0 v 0.94078 49.46671 h 24.94242 24.94823 v -50.40749 h -24.94823 z m 119.99656,0 v 0.94078 49.46671 h 24.94822 24.94242 V 631.32982 H 565.71299 Z M 84.768582,689.13583 v 0.94659 49.46671 h 24.948228 24.94242 v -50.4133 h -24.94242 z m 143.998188,0 v 0.94659 49.46671 h 24.94822 24.94242 v -50.4133 h -24.94242 z m 120.00235,0 v 0.94659 49.46671 h 24.94242 24.94823 v -50.4133 h -24.94823 z m 71.99909,0 v 0.94659 49.46671 h 24.94242 24.94823 v -50.4133 h -24.94823 z m 119.99656,0 v 0.94659 49.46671 h 24.94822 24.94242 v -50.4133 h -24.94242 z"
|
||||||
|
transform="matrix(0.15572681,0,0,0.15572681,1.390094,49.845283)" />
|
||||||
|
</g>
|
||||||
|
<defs
|
||||||
|
id="defs2">
|
||||||
|
<rect
|
||||||
|
x="3.6285765"
|
||||||
|
y="28.230612"
|
||||||
|
width="198.25528"
|
||||||
|
height="291.22577"
|
||||||
|
id="rect835" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="1.3460637"
|
||||||
|
inkscape:cx="111.74922"
|
||||||
|
inkscape:cy="158.4106"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="svg8"
|
||||||
|
inkscape:document-rotation="0"
|
||||||
|
showgrid="false"
|
||||||
|
fit-margin-top="1"
|
||||||
|
fit-margin-left="1"
|
||||||
|
fit-margin-right="1"
|
||||||
|
fit-margin-bottom="1"
|
||||||
|
inkscape:window-width="1360"
|
||||||
|
inkscape:window-height="745"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="23"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:showpageshadow="true"
|
||||||
|
inkscape:pagecheckerboard="1"
|
||||||
|
inkscape:deskcolor="#d1d1d1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata5">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 9.9 KiB |
BIN
assets/root/icon-192.png
Normal file
After Width: | Height: | Size: 4 KiB |
BIN
assets/root/icon-512.png
Normal file
After Width: | Height: | Size: 7.2 KiB |
83
assets/root/logo.svg
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="54.915634mm"
|
||||||
|
height="30.470612mm"
|
||||||
|
viewBox="-1 -13.22 54.916672 30.471189"
|
||||||
|
version="1.1"
|
||||||
|
id="svg8"
|
||||||
|
inkscape:version="1.0.2 (e86c870879, 2021-01-15)"
|
||||||
|
sodipodi:docname="INKSCAPE_Logo_TKA.svg"
|
||||||
|
inkscape:export-filename="icon-512.png"
|
||||||
|
inkscape:export-xdpi="236.80827"
|
||||||
|
inkscape:export-ydpi="236.80827"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||||
|
<g
|
||||||
|
aria-label=" ████████╗██╗ ██╗ █████╗ ╚══██╔══╝██║ ██╔╝██╔══██╗ ██║ █████╔╝ ███████║ ██║ ██╔═██╗ ██╔══██║ ██║ ██║ ██╗██║ ██║ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝"
|
||||||
|
id="text833-8"
|
||||||
|
style="font-size:10.5833px;line-height:1.25;font-family:'Copperplate Gothic Bold';-inkscape-font-specification:'Copperplate Gothic Bold, ';white-space:pre;shape-inside:url(#rect835);display:inline"
|
||||||
|
inkscape:label="TKA Blanc"
|
||||||
|
transform="matrix(0.57142858,0,0,0.57142858,-1.930636,-81.450047)">
|
||||||
|
<path
|
||||||
|
id="path1748"
|
||||||
|
style="color:#000000;font-size:10.5833px;line-height:1.25;font-family:'Copperplate Gothic Bold';-inkscape-font-specification:'Noto Sans Mono';white-space:pre;shape-inside:url(#rect835);display:inline;fill:#808080;fill-opacity:0.503856;stroke:none;stroke-width:0.401402;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
|
||||||
|
d="m 206.65832,477.40693 v 4.35548 h 12.42184 v 34.65225 25.84255 H 205.95563 181.954 157.95237 147.04042 v 32.72422 h 0.0348 v 57.05107 57.81182 l 0.0465,57.05687 h -0.0465 v 26.5975 h -13.11873 -0.48201 -23.51962 -13.600734 v -33.94956 h -4.355487 v 38.29924 h 17.956221 23.51962 0.48201 17.47421 v -29.43728 h 0.0406 l -0.0406,-58.56677 V 632.0325 573.47153 h -0.0406 v -26.86464 h 6.56227 24.00163 24.00163 17.47421 v -30.19223 -39.00773 z m 71.99909,0 v 4.35548 h 12.42185 v 34.65225 57.10333 h 4.34968 v -57.10333 -39.00773 z m 120.00236,0 v 4.35548 h 12.41604 v 34.65225 25.84255 h -13.12453 -10.91776 l 0.0465,31.96927 v 25.84255 H 373.95545 363.0377 v 31.26078 h 4.34968 v -26.9111 h 6.56807 17.47421 v -30.19223 l -0.0407,-27.61959 h 6.56227 17.48001 v -30.19223 -39.00773 z m 167.99982,0 v 4.35548 h 12.41603 v 33.94376 h 4.34968 v -38.29924 z m -360.00127,7.03846 v 4.35549 h 5.38338 v 27.61378 18.80409 H 205.95563 181.954 157.95237 139.99615 v 39.00773 57.80602 57.81182 l 0.0406,57.81182 v 18.80409 h -6.08026 -0.48201 -23.51962 -6.56227 v -26.9111 h -4.355485 v 31.26077 h 10.917755 23.51962 0.48201 10.43575 v -23.15376 l -0.0407,-57.81182 V 632.0325 574.22648 539.56843 h 13.60074 24.00163 24.00163 10.43575 v -23.15377 -31.96927 z m 71.99909,0 v 4.35549 h 5.38338 v 26.85883 h -0.0407 v 57.85828 h 4.34968 v -56.34838 h 0.0406 v -32.72422 z m 120.00236,0 v 4.35549 h 5.37757 v 27.61378 18.80409 h -6.08606 -17.95042 l 0.0349,39.00773 v 18.79828 h -6.08026 -17.95622 v 38.30505 h 4.34968 v -33.94956 h 13.60654 10.43575 v -23.15377 l -0.0407,-34.65805 h 13.60074 10.43574 v -23.15377 -31.96927 z m 167.99982,0 v 4.35549 h 5.37757 v 26.90529 h 4.34968 V 484.44539 Z M 19.999597,508.30765 v 38.29924 h 17.956219 24.001633 22.811133 v -4.34968 H 61.957449 37.955816 24.349276 v -33.94956 z m 7.038466,0 v 31.26078 h 10.917753 24.001633 22.811133 v -4.34968 H 61.957449 37.955816 31.387742 v -26.9111 z m 448.957717,26.9111 v 0.75495 37.54429 h 4.35549 v -33.94956 h 13.60073 24.00163 22.81114 v -4.34968 H 517.95363 493.952 Z m 114.65963,0 v 4.34968 h 12.42185 v 34.65805 57.80602 57.81182 57.81182 25.84255 h -13.12453 -0.48201 -23.51963 -13.60073 v -33.94956 h -4.35549 v 38.29924 h 17.95622 23.51963 0.48201 17.47421 V 747.65614 689.84432 632.0325 574.22648 535.21875 Z m -107.62116,7.03846 v 0.75495 30.50583 h 4.35548 v -26.9111 h 6.56227 24.00163 22.81114 v -4.34968 H 517.95363 493.952 Z m 107.62116,0 v 4.34968 h 5.38338 v 26.86464 h -0.0406 v 58.56097 57.81182 58.56677 h 0.0406 v 18.04914 h -6.08606 -0.48201 -23.51963 -6.56226 v -26.9111 h -4.34968 v 31.26077 h 10.91194 23.51963 0.48201 10.43574 v -23.90871 h -0.0407 V 689.84432 632.0325 574.98143 h 0.0407 V 542.25721 Z M 284.00014,650.83658 v 0.75495 38.25279 l 0.0407,57.81182 v 18.80409 h -6.08607 -24.00163 -6.56226 v -26.9111 h -4.34968 v 31.26077 h 10.91194 24.00163 10.43575 v -23.15376 l -0.0406,-57.81182 v -34.65225 h 13.60073 22.81694 v -4.35549 h -22.81694 z m 90.658,0 v 4.35549 h 12.42184 v 33.94376 h 4.34968 v -38.29925 z m 101.33764,0 v 0.75495 38.25279 l 0.0406,57.81182 v 18.80409 h -6.08606 -23.99583 -6.56807 v -26.9111 h -4.34968 v 31.26077 h 10.91775 23.99583 10.43574 v -23.15376 l -0.0348,-57.81182 v -34.65225 h 13.60073 24.00163 22.81114 v -4.35549 H 517.95363 493.952 Z m -184.95717,7.04428 v 0.75495 31.96346 h 0.0406 l 0.0407,56.30192 h -0.0407 v 26.5975 h -13.12454 -24.00163 -13.60073 v -33.94956 h -4.35549 v 38.29924 h 17.95622 24.00163 17.47422 v -29.43728 h 0.0406 l -0.0406,-59.32172 h -0.0407 v -26.85884 h 6.56227 22.81694 v -4.34967 h -22.81694 z m 83.61953,0 v 4.34967 h 5.37757 v 26.9053 h 4.35549 v -31.25497 z m 108.37611,0 v 0.75495 31.96346 h 0.0407 l 0.0406,56.30192 h -0.0406 v 26.5975 H 469.95037 445.95454 432.348 v -33.94956 h -4.34968 v 38.29924 h 17.95622 23.99583 17.48002 v -29.43728 h 0.0407 l -0.0407,-59.32172 h -0.0407 v -26.85884 h 6.56227 24.00163 22.81114 v -4.34967 H 517.95363 493.952 Z M 331.9976,681.73731 v 38.29924 h 16.77152 v -4.34968 h -12.42184 v -33.94956 z m 7.03846,0 v 31.26077 h 9.73306 v -4.34968 h -5.37757 v -26.91109 z m 59.62371,26.91109 v 4.34968 h 12.41604 v 34.65806 25.84255 h -13.12453 -23.99583 -13.60654 v -33.94956 h -4.34968 v 38.29924 h 17.95622 23.99583 17.48001 V 747.65614 708.6484 Z m 0,7.03847 v 4.34968 h 5.37757 v 27.61959 18.80409 h -6.08606 -23.99583 -6.56807 v -26.9111 h -4.34968 v 31.26077 h 10.91775 23.99583 10.43574 v -23.15376 -31.96927 z"
|
||||||
|
transform="matrix(0.15572681,0,0,0.15572681,1.390094,49.845283)" />
|
||||||
|
<path
|
||||||
|
id="path1774"
|
||||||
|
style="color:#000000;font-size:10.5833px;line-height:1.25;font-family:'Copperplate Gothic Bold';-inkscape-font-specification:'Noto Sans Mono';white-space:pre;shape-inside:url(#rect835);display:inline;fill:#9e9e9e;fill-opacity:1;stroke:none;stroke-width:1.88976;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:none"
|
||||||
|
d="m 12.76949,457.90016 v 0.94078 49.46671 h 24.948225 23.995826 24.001633 24.001636 23.99582 24.00164 24.00163 24.94242 V 457.90016 H 181.7159 157.71427 133.71263 109.71681 85.715174 61.713541 37.717715 Z m 215.99728,0 v 0.94078 49.46671 h 24.94822 24.94242 v -50.40749 h -24.94242 z m 120.00235,0 v 0.94078 49.46671 h 24.94242 24.94823 v -50.40749 h -24.94823 z m 96.00073,0 v 0.94078 49.46671 h 24.94242 24.00163 24.00163 23.99583 24.94822 V 457.90016 H 541.71136 517.71553 493.7139 469.71227 Z M 84.768582,515.70617 v 0.9466 49.4667 h 24.948228 24.94242 v -50.4133 h -24.94242 z m 143.998188,0 v 0.9466 49.4667 h 24.94822 24.94242 v -50.4133 h -24.94242 z m 96.00072,0 v 0.9466 49.4667 h 24.94823 24.94241 v -50.4133 h -24.94241 z m 96.00072,0 v 0.9466 49.4667 h 24.94242 24.94823 v -50.4133 h -24.94823 z m 119.99656,0 v 0.9466 49.4667 h 24.94822 24.94242 v -50.4133 H 565.71299 Z M 84.768582,573.51799 v 0.9466 49.46671 h 24.948228 24.94242 v -50.41331 h -24.94242 z m 143.998188,0 v 0.9466 49.46671 h 24.94822 24.00163 23.99583 24.00163 24.94242 v -50.41331 h -24.94242 -24.00163 -23.99583 -24.00163 z m 192.00144,0 v 0.9466 49.46671 h 24.94242 24.00164 24.00163 24.00163 23.99583 24.00163 24.94242 V 573.51799 H 565.71299 541.71136 517.71553 493.7139 469.71227 445.71063 Z M 84.768582,631.32982 v 0.94078 49.46671 h 24.948228 24.94242 v -50.40749 h -24.94242 z m 143.998188,0 v 0.94078 49.46671 h 24.94822 24.94242 v -50.40749 h -24.94242 z m 96.00072,0 v 0.94078 49.46671 h 24.94823 24.94241 v -50.40749 h -24.94241 z m 96.00072,0 v 0.94078 49.46671 h 24.94242 24.94823 v -50.40749 h -24.94823 z m 119.99656,0 v 0.94078 49.46671 h 24.94822 24.94242 V 631.32982 H 565.71299 Z M 84.768582,689.13583 v 0.94659 49.46671 h 24.948228 24.94242 v -50.4133 h -24.94242 z m 143.998188,0 v 0.94659 49.46671 h 24.94822 24.94242 v -50.4133 h -24.94242 z m 120.00235,0 v 0.94659 49.46671 h 24.94242 24.94823 v -50.4133 h -24.94823 z m 71.99909,0 v 0.94659 49.46671 h 24.94242 24.94823 v -50.4133 h -24.94823 z m 119.99656,0 v 0.94659 49.46671 h 24.94822 24.94242 v -50.4133 h -24.94242 z"
|
||||||
|
transform="matrix(0.15572681,0,0,0.15572681,1.390094,49.845283)" />
|
||||||
|
</g>
|
||||||
|
<defs
|
||||||
|
id="defs2">
|
||||||
|
<rect
|
||||||
|
x="3.6285765"
|
||||||
|
y="28.230612"
|
||||||
|
width="198.25528"
|
||||||
|
height="291.22577"
|
||||||
|
id="rect835" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="1.3460637"
|
||||||
|
inkscape:cx="111.74922"
|
||||||
|
inkscape:cy="158.4106"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="svg8"
|
||||||
|
inkscape:document-rotation="0"
|
||||||
|
showgrid="false"
|
||||||
|
fit-margin-top="1"
|
||||||
|
fit-margin-left="1"
|
||||||
|
fit-margin-right="1"
|
||||||
|
fit-margin-bottom="1"
|
||||||
|
inkscape:window-width="1360"
|
||||||
|
inkscape:window-height="745"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="23"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:showpageshadow="true"
|
||||||
|
inkscape:pagecheckerboard="1"
|
||||||
|
inkscape:deskcolor="#d1d1d1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata5">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 9.9 KiB |
6
assets/root/manifest.webmanifest
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"icons": [
|
||||||
|
{ "src": "/icon-192.png", "type": "image/png", "sizes": "192x192" },
|
||||||
|
{ "src": "/icon-512.png", "type": "image/png", "sizes": "512x512" }
|
||||||
|
]
|
||||||
|
}
|
2
assets/root/robots.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
User-Agent: *
|
||||||
|
Disallow: /
|
BIN
assets/screenshots/startpage.png
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
assets/screenshots/staticrypt.png
Normal file
After Width: | Height: | Size: 18 KiB |
662
assets/source/index.html
Normal file
|
@ -0,0 +1,662 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="color-scheme" content="dark light" />
|
||||||
|
<meta name="robots" content="noindex" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
|
||||||
|
<link rel="icon" href="favicon.ico" sizes="any">
|
||||||
|
<link rel="icon" href="favicon.svg" type="image/svg+xml">
|
||||||
|
<link rel="manifest" href="manifest.webmanifest">
|
||||||
|
|
||||||
|
<title>TKA - Start Page</title>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--color-background: #303030;
|
||||||
|
--color-text-subtle: #b3b3b3;
|
||||||
|
--color-text: #ff4000;
|
||||||
|
--font-family: monospace;
|
||||||
|
--font-size-1: 1rem;
|
||||||
|
--font-size-2: 3rem;
|
||||||
|
--font-size-base: clamp(16px, 1.2vw, 18px);
|
||||||
|
--font-weight-bold: 700;
|
||||||
|
--font-weight-normal: 400;
|
||||||
|
--line-height-base: 1.4;
|
||||||
|
--space-1: 0.5rem;
|
||||||
|
--space-2: 1rem;
|
||||||
|
--space-3: 4rem;
|
||||||
|
--transition-speed: 200ms;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const CONFIG = {
|
||||||
|
commandPathDelimiter: '/',
|
||||||
|
commandSearchDelimiter: ' ',
|
||||||
|
defaultSearchTemplate: 'https://duckduckgo.com/?kl=fr-fr&kad=fr_FR&kp=-2&kz=-1&kc=-1&k1=-1&kaj=m&kay=i&kak=-1&kax=-1&kaq=-1&kao=-1&kau=-1&kap=-1&k7=303030&kae=d&kj=262626&k9=f5f5f5&kaa=b3b3b3&k8=b3b3b3&kx=ff4000&k21=363636&q={}',
|
||||||
|
openLinksInNewTab: true,
|
||||||
|
suggestionLimit: 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
const COMMANDS = new Map([
|
||||||
|
['b', {
|
||||||
|
name: 'Blog',
|
||||||
|
url: 'https://myblog.net',
|
||||||
|
suggestions: ['myblog.net']
|
||||||
|
}],
|
||||||
|
['g', {
|
||||||
|
name: 'GitHub',
|
||||||
|
searchTemplate: '/search?q={}',
|
||||||
|
suggestions: [
|
||||||
|
'github.com',
|
||||||
|
'g/trending',
|
||||||
|
'g/collections',
|
||||||
|
'gist.github.com',
|
||||||
|
],
|
||||||
|
url: 'https://github.com',
|
||||||
|
}],
|
||||||
|
['m', {
|
||||||
|
name: 'Webmail',
|
||||||
|
url: 'https://mywebmail.tld',
|
||||||
|
suggestions: ['mywebmail.tld', 'm/?admin']
|
||||||
|
}],
|
||||||
|
['n', {
|
||||||
|
name: 'nb',
|
||||||
|
suggestions: ['localhost:6789', 'n/dev', 'n/home', 'n/sys',],
|
||||||
|
url: 'http://localhost:6789',
|
||||||
|
}],
|
||||||
|
['n/dev', {
|
||||||
|
searchTemplate: ':6789/dev:?--query={}&--limit=30&--page=1&--columns=70',
|
||||||
|
url: 'http://localhost:6789/dev:',
|
||||||
|
}],
|
||||||
|
['n/home', {
|
||||||
|
searchTemplate: ':6789/home:?--query={}&--limit=30&--page=1&--columns=70',
|
||||||
|
url: 'http://localhost:6789/home:',
|
||||||
|
}],
|
||||||
|
['n/sys', {
|
||||||
|
searchTemplate: ':6789/sys:?--query={}&--limit=30&--page=1&--columns=70',
|
||||||
|
url: 'http://localhost:6789/sys:',
|
||||||
|
}],
|
||||||
|
['N', {
|
||||||
|
name: 'Ntfy',
|
||||||
|
url: 'https://ntfy.domain.tld',
|
||||||
|
suggestions: ['ntfy.domain.tld', 'N/tests']
|
||||||
|
}],
|
||||||
|
['t', {
|
||||||
|
name: 'Translate',
|
||||||
|
searchTemplate: '/?sl=fr&tl=en&text={}',
|
||||||
|
url: 'https://translate.google.com',
|
||||||
|
suggestions: ['translate.google.com']
|
||||||
|
}],
|
||||||
|
['w', {
|
||||||
|
name: 'Wikipedia',
|
||||||
|
searchTemplate: '/w/index.php?search={}',
|
||||||
|
suggestions: ['fr.wikipedia.org', 'w/wiki/Special:Random'],
|
||||||
|
url: 'https://fr.wikipedia.org/wiki/Main_Page'
|
||||||
|
}],
|
||||||
|
['y', {
|
||||||
|
name: 'YouTube',
|
||||||
|
searchTemplate: '/results?search_query={}',
|
||||||
|
suggestions: ['youtube.com', 'y/feed/subscriptions'],
|
||||||
|
url: 'https://youtube.com'
|
||||||
|
}],
|
||||||
|
['0', {
|
||||||
|
name: 'localhost',
|
||||||
|
searchTemplate: ':{}',
|
||||||
|
suggestions: ['0 6789', '0 8000'],
|
||||||
|
url: 'http://localhost:3000'
|
||||||
|
}],
|
||||||
|
['?', {
|
||||||
|
name: 'README',
|
||||||
|
url: 'https://github.com/xvvvyz/tilde',
|
||||||
|
suggestions: ['git.tkapias.net/tkapias/stilde']
|
||||||
|
}],
|
||||||
|
]);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template id="commands-template">
|
||||||
|
<style>
|
||||||
|
.commands {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(20ch, 1fr));
|
||||||
|
gap: var(--space-1);
|
||||||
|
list-style: none;
|
||||||
|
margin: 0 auto;
|
||||||
|
min-width: 50vw;
|
||||||
|
padding: 0 0 0 var(--space-1);
|
||||||
|
justify-items: start;
|
||||||
|
align-items: center;
|
||||||
|
place-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.command {
|
||||||
|
outline: 0;
|
||||||
|
padding: var(--space-1);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.key {
|
||||||
|
color: var(--color-text);
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
width: 3ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name {
|
||||||
|
color: var(--color-text-subtle);
|
||||||
|
transition: color var(--transition-speed);
|
||||||
|
}
|
||||||
|
|
||||||
|
.command:where(:focus, :hover) .name {
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<nav>
|
||||||
|
<menu class="commands"></menu>
|
||||||
|
</nav>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template id="command-template">
|
||||||
|
<li>
|
||||||
|
<a class="command" rel="noopener noreferrer">
|
||||||
|
<span class="key"></span>
|
||||||
|
<span class="name"></span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script type="module">
|
||||||
|
class Commands extends HTMLElement {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.attachShadow({ mode: 'open' });
|
||||||
|
const template = document.getElementById('commands-template');
|
||||||
|
const clone = template.content.cloneNode(true);
|
||||||
|
const commands = clone.querySelector('.commands');
|
||||||
|
const commandTemplate = document.getElementById('command-template');
|
||||||
|
|
||||||
|
for (const [key, { name, url }] of COMMANDS.entries()) {
|
||||||
|
if (!name || !url) continue;
|
||||||
|
const clone = commandTemplate.content.cloneNode(true);
|
||||||
|
const command = clone.querySelector('.command');
|
||||||
|
command.href = url;
|
||||||
|
if (CONFIG.openLinksInNewTab) command.target = '_blank';
|
||||||
|
clone.querySelector('.key').innerText = key;
|
||||||
|
clone.querySelector('.name').innerText = name;
|
||||||
|
commands.append(clone);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.shadowRoot.append(clone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define('commands-component', Commands);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template id="search-template">
|
||||||
|
<style>
|
||||||
|
input,
|
||||||
|
button {
|
||||||
|
-moz-appearance: none;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
background: transparent;
|
||||||
|
border: 0;
|
||||||
|
display: block;
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog {
|
||||||
|
align-items: center;
|
||||||
|
background: var(--color-background);
|
||||||
|
border: none;
|
||||||
|
display: none;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
left: 0;
|
||||||
|
padding: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog[open] {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input {
|
||||||
|
color: var(--color-text);
|
||||||
|
font-size: var(--font-size-2);
|
||||||
|
font-weight: var(--font-weight-bold);
|
||||||
|
padding: 0;
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.suggestions {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
list-style: none;
|
||||||
|
margin: var(--space-2) 0 0;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.suggestion {
|
||||||
|
color: var(--color-text);
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: var(--font-size-1);
|
||||||
|
padding: var(--space-2);
|
||||||
|
position: relative;
|
||||||
|
transition: color var(--transition-speed);
|
||||||
|
white-space: nowrap;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.suggestion:where(:focus, :hover) {
|
||||||
|
color: var(--color-background);
|
||||||
|
}
|
||||||
|
|
||||||
|
.suggestion::before {
|
||||||
|
background-color: var(--color-text);
|
||||||
|
bottom: var(--space-2);
|
||||||
|
content: ' ';
|
||||||
|
left: var(--space-2);
|
||||||
|
opacity: 0;
|
||||||
|
position: absolute;
|
||||||
|
right: var(--space-2);
|
||||||
|
top: var(--space-2);
|
||||||
|
transform: translateY(0.5em);
|
||||||
|
transition: all var(--transition-speed);
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.suggestion:where(:focus, :hover)::before {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.match {
|
||||||
|
color: var(--color-text-subtle);
|
||||||
|
transition: color var(--transition-speed);
|
||||||
|
}
|
||||||
|
|
||||||
|
.suggestion:where(:focus, :hover) .match {
|
||||||
|
color: var(--color-background);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 700px) {
|
||||||
|
.suggestions {
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<dialog class="dialog">
|
||||||
|
<form autocomplete="off" class="form" method="dialog" spellcheck="false">
|
||||||
|
<input class="input" title="search" type="text" />
|
||||||
|
<menu class="suggestions"></menu>
|
||||||
|
</form>
|
||||||
|
</dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template id="suggestion-template">
|
||||||
|
<li>
|
||||||
|
<button class="suggestion" type="button"></button>
|
||||||
|
</li>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template id="match-template">
|
||||||
|
<span class="match"></span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script type="module">
|
||||||
|
class Search extends HTMLElement {
|
||||||
|
#dialog;
|
||||||
|
#form;
|
||||||
|
#input;
|
||||||
|
#suggestions;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.attachShadow({ mode: 'open' });
|
||||||
|
const template = document.getElementById('search-template');
|
||||||
|
const clone = template.content.cloneNode(true);
|
||||||
|
this.#dialog = clone.querySelector('.dialog');
|
||||||
|
this.#form = clone.querySelector('.form');
|
||||||
|
this.#input = clone.querySelector('.input');
|
||||||
|
this.#suggestions = clone.querySelector('.suggestions');
|
||||||
|
this.#form.addEventListener('submit', this.#onSubmit, false);
|
||||||
|
this.#input.addEventListener('input', this.#onInput);
|
||||||
|
this.#suggestions.addEventListener('click', this.#onSuggestionClick);
|
||||||
|
document.addEventListener('keydown', this.#onKeydown);
|
||||||
|
this.shadowRoot.append(clone);
|
||||||
|
const shadows = document.querySelector('#logo path#shadows');
|
||||||
|
}
|
||||||
|
|
||||||
|
static #attachSearchPrefix(array, { key, splitBy }) {
|
||||||
|
if (!splitBy) return array;
|
||||||
|
return array.map((search) => `${key}${splitBy}${search}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
static #escapeRegexCharacters(s) {
|
||||||
|
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
|
||||||
|
}
|
||||||
|
|
||||||
|
static #fetchDuckDuckGoSuggestions(search) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
window.autocompleteCallback = (res) => {
|
||||||
|
const suggestions = [];
|
||||||
|
|
||||||
|
for (const item of res) {
|
||||||
|
if (item.phrase === search.toLowerCase()) continue;
|
||||||
|
suggestions.push(item.phrase);
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(suggestions);
|
||||||
|
};
|
||||||
|
|
||||||
|
const script = document.createElement('script');
|
||||||
|
document.querySelector('head').appendChild(script);
|
||||||
|
script.src = `https://duckduckgo.com/ac/?callback=autocompleteCallback&q=${search}`;
|
||||||
|
script.onload = script.remove;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static #formatSearchUrl(url, searchPath, search) {
|
||||||
|
if (!searchPath) return url;
|
||||||
|
const [baseUrl] = Search.#splitUrl(url);
|
||||||
|
const urlQuery = encodeURIComponent(search);
|
||||||
|
searchPath = searchPath.replace(/{}/g, urlQuery);
|
||||||
|
return baseUrl + searchPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
static #hasProtocol(s) {
|
||||||
|
return /^[a-zA-Z]+:\/\//i.test(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static #isUrl(s) {
|
||||||
|
return /^((https?:\/\/)?[\w-]+(\.[\w-]+)+\.?(:\d+)?(\/\S*)?)$/i.test(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static #parseQuery = (raw) => {
|
||||||
|
const query = raw.trim();
|
||||||
|
|
||||||
|
if (this.#isUrl(query)) {
|
||||||
|
const url = this.#hasProtocol(query) ? query : `https://${query}`;
|
||||||
|
return { query, url };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (COMMANDS.has(query)) {
|
||||||
|
const { command, key, url } = COMMANDS.get(query);
|
||||||
|
return command ? Search.#parseQuery(command) : { key, query, url };
|
||||||
|
}
|
||||||
|
|
||||||
|
let splitBy = CONFIG.commandSearchDelimiter;
|
||||||
|
const [searchKey, rawSearch] = query.split(new RegExp(`${splitBy}(.*)`));
|
||||||
|
|
||||||
|
if (COMMANDS.has(searchKey)) {
|
||||||
|
const { searchTemplate, url: base } = COMMANDS.get(searchKey);
|
||||||
|
const search = rawSearch.trim();
|
||||||
|
const url = Search.#formatSearchUrl(base, searchTemplate, search);
|
||||||
|
return { key: searchKey, query, search, splitBy, url };
|
||||||
|
}
|
||||||
|
|
||||||
|
splitBy = CONFIG.commandPathDelimiter;
|
||||||
|
const [pathKey, path] = query.split(new RegExp(`${splitBy}(.*)`));
|
||||||
|
|
||||||
|
if (COMMANDS.has(pathKey)) {
|
||||||
|
const { url: base } = COMMANDS.get(pathKey);
|
||||||
|
const [baseUrl] = Search.#splitUrl(base);
|
||||||
|
const url = `${baseUrl}/${path}`;
|
||||||
|
return { key: pathKey, path, query, splitBy, url };
|
||||||
|
}
|
||||||
|
|
||||||
|
const [baseUrl, rest] = Search.#splitUrl(CONFIG.defaultSearchTemplate);
|
||||||
|
const url = Search.#formatSearchUrl(baseUrl, rest, query);
|
||||||
|
return { query, search: query, url };
|
||||||
|
};
|
||||||
|
|
||||||
|
static #splitUrl(url) {
|
||||||
|
const parser = document.createElement('a');
|
||||||
|
parser.href = url;
|
||||||
|
const baseUrl = `${parser.protocol}//${parser.hostname}`;
|
||||||
|
const rest = `${parser.pathname}${parser.search}`;
|
||||||
|
return [baseUrl, rest];
|
||||||
|
}
|
||||||
|
|
||||||
|
#close() {
|
||||||
|
this.#input.value = '';
|
||||||
|
this.#input.blur();
|
||||||
|
this.#dialog.close();
|
||||||
|
this.#suggestions.innerHTML = '';
|
||||||
|
shadows.style.fill = '#808080'
|
||||||
|
}
|
||||||
|
|
||||||
|
#execute(query) {
|
||||||
|
const { url } = Search.#parseQuery(query);
|
||||||
|
const target = CONFIG.openLinksInNewTab ? '_blank' : '_self';
|
||||||
|
window.open(url, target, 'noopener noreferrer');
|
||||||
|
this.#close();
|
||||||
|
}
|
||||||
|
|
||||||
|
#focusNextSuggestion(previous = false) {
|
||||||
|
const active = this.shadowRoot.activeElement;
|
||||||
|
let nextIndex;
|
||||||
|
|
||||||
|
if (active.dataset.index) {
|
||||||
|
const activeIndex = Number(active.dataset.index);
|
||||||
|
nextIndex = previous ? activeIndex - 1 : activeIndex + 1;
|
||||||
|
} else {
|
||||||
|
nextIndex = previous ? this.#suggestions.childElementCount - 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const next = this.#suggestions.children[nextIndex];
|
||||||
|
if (next) next.querySelector('.suggestion').focus();
|
||||||
|
else this.#input.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
#onInput = async () => {
|
||||||
|
shadows.style.fill = '#ff4000'
|
||||||
|
const oq = Search.#parseQuery(this.#input.value);
|
||||||
|
|
||||||
|
if (!oq.query) {
|
||||||
|
this.#close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let suggestions = COMMANDS.get(oq.query)?.suggestions ?? [];
|
||||||
|
|
||||||
|
if (oq.search && suggestions.length < CONFIG.suggestionLimit) {
|
||||||
|
const res = await Search.#fetchDuckDuckGoSuggestions(oq.search);
|
||||||
|
const formatted = Search.#attachSearchPrefix(res, oq);
|
||||||
|
suggestions = suggestions.concat(formatted);
|
||||||
|
}
|
||||||
|
|
||||||
|
const nq = Search.#parseQuery(this.#input.value);
|
||||||
|
if (nq.query !== oq.query) return;
|
||||||
|
this.#renderSuggestions(suggestions, oq.query);
|
||||||
|
};
|
||||||
|
|
||||||
|
#onKeydown = (e) => {
|
||||||
|
if (!this.#dialog.open) {
|
||||||
|
this.#dialog.show();
|
||||||
|
this.#input.focus();
|
||||||
|
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
// close the search dialog before the next repaint if a character is
|
||||||
|
// not produced (e.g. if you type shift, control, alt etc.)
|
||||||
|
if (!this.#input.value) this.#close();
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.key === 'Escape') {
|
||||||
|
this.#close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const alt = e.altKey ? 'alt-' : '';
|
||||||
|
const ctrl = e.ctrlKey ? 'ctrl-' : '';
|
||||||
|
const meta = e.metaKey ? 'meta-' : '';
|
||||||
|
const shift = e.shiftKey ? 'shift-' : '';
|
||||||
|
const modifierPrefixedKey = `${alt}${ctrl}${meta}${shift}${e.key}`;
|
||||||
|
|
||||||
|
if (/^(ArrowDown|Tab|ctrl-n)$/.test(modifierPrefixedKey)) {
|
||||||
|
e.preventDefault();
|
||||||
|
this.#focusNextSuggestion();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (/^(ArrowUp|ctrl-p|shift-Tab)$/.test(modifierPrefixedKey)) {
|
||||||
|
e.preventDefault();
|
||||||
|
this.#focusNextSuggestion(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#onSubmit = () => {
|
||||||
|
this.#execute(this.#input.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
#onSuggestionClick = (e) => {
|
||||||
|
const ref = e.target.closest('.suggestion');
|
||||||
|
if (!ref) return;
|
||||||
|
this.#execute(ref.dataset.suggestion);
|
||||||
|
};
|
||||||
|
|
||||||
|
#renderSuggestions(suggestions, query) {
|
||||||
|
this.#suggestions.innerHTML = '';
|
||||||
|
const sliced = suggestions.slice(0, CONFIG.suggestionLimit);
|
||||||
|
const template = document.getElementById('suggestion-template');
|
||||||
|
|
||||||
|
for (const [index, suggestion] of sliced.entries()) {
|
||||||
|
const clone = template.content.cloneNode(true);
|
||||||
|
const ref = clone.querySelector('.suggestion');
|
||||||
|
ref.dataset.index = index;
|
||||||
|
ref.dataset.suggestion = suggestion;
|
||||||
|
const escapedQuery = Search.#escapeRegexCharacters(query);
|
||||||
|
const matched = suggestion.match(new RegExp(escapedQuery, 'i'));
|
||||||
|
|
||||||
|
if (matched) {
|
||||||
|
const template = document.getElementById('match-template');
|
||||||
|
const clone = template.content.cloneNode(true);
|
||||||
|
const matchRef = clone.querySelector('.match');
|
||||||
|
const pre = suggestion.slice(0, matched.index);
|
||||||
|
const post = suggestion.slice(matched.index + matched[0].length);
|
||||||
|
matchRef.innerText = matched[0];
|
||||||
|
matchRef.insertAdjacentHTML('beforebegin', pre);
|
||||||
|
matchRef.insertAdjacentHTML('afterend', post);
|
||||||
|
ref.append(clone);
|
||||||
|
} else {
|
||||||
|
ref.innerText = suggestion;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.#suggestions.append(clone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define('search-component', Search);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
html {
|
||||||
|
background-color: var(--color-background);
|
||||||
|
font-family: var(--font-family);
|
||||||
|
font-size: var(--font-size-base);
|
||||||
|
line-height: var(--line-height-base);
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: var(--color-background);
|
||||||
|
min-height: 70vh;
|
||||||
|
margin: 5vh 15vw 15vh 15vw;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
align-items: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0 10vw 15vh 10vw;
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#logo {
|
||||||
|
padding: 15vh 10vw 10vh 10vw;
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
#logo path#characters {
|
||||||
|
fill-opacity: 0.5 !important;
|
||||||
|
transition: fill 2s, fill-opacity 1s;
|
||||||
|
}
|
||||||
|
#logo path#characters:hover {
|
||||||
|
fill: #ff4000 !important;
|
||||||
|
fill-opacity: 0.8 !important;
|
||||||
|
transition: fill 2s, fill-opacity 1s;
|
||||||
|
}
|
||||||
|
#logo path#shadows {
|
||||||
|
fill: #808080;
|
||||||
|
transition: fill 2s;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="box-container">
|
||||||
|
|
||||||
|
<svg
|
||||||
|
preserveAspectRatio=true
|
||||||
|
viewBox="-1 -13.22 54.916672 30.471189"
|
||||||
|
version="1.1"
|
||||||
|
id="logo"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<g
|
||||||
|
id="trigram"
|
||||||
|
style="shape-inside:url(#rect835);display:inline"
|
||||||
|
transform="matrix(0.57142858,0,0,0.57142858,-1.930636,-81.450047)">
|
||||||
|
<path
|
||||||
|
id="shadows"
|
||||||
|
style="shape-inside:url(#rect835);display:inline;fill:#808080;fill-opacity:0.503856;stroke:none;stroke-width:0.401402;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
|
||||||
|
d="m 206.65832,477.40693 v 4.35548 h 12.42184 v 34.65225 25.84255 H 205.95563 181.954 157.95237 147.04042 v 32.72422 h 0.0348 v 57.05107 57.81182 l 0.0465,57.05687 h -0.0465 v 26.5975 h -13.11873 -0.48201 -23.51962 -13.600734 v -33.94956 h -4.355487 v 38.29924 h 17.956221 23.51962 0.48201 17.47421 v -29.43728 h 0.0406 l -0.0406,-58.56677 V 632.0325 573.47153 h -0.0406 v -26.86464 h 6.56227 24.00163 24.00163 17.47421 v -30.19223 -39.00773 z m 71.99909,0 v 4.35548 h 12.42185 v 34.65225 57.10333 h 4.34968 v -57.10333 -39.00773 z m 120.00236,0 v 4.35548 h 12.41604 v 34.65225 25.84255 h -13.12453 -10.91776 l 0.0465,31.96927 v 25.84255 H 373.95545 363.0377 v 31.26078 h 4.34968 v -26.9111 h 6.56807 17.47421 v -30.19223 l -0.0407,-27.61959 h 6.56227 17.48001 v -30.19223 -39.00773 z m 167.99982,0 v 4.35548 h 12.41603 v 33.94376 h 4.34968 v -38.29924 z m -360.00127,7.03846 v 4.35549 h 5.38338 v 27.61378 18.80409 H 205.95563 181.954 157.95237 139.99615 v 39.00773 57.80602 57.81182 l 0.0406,57.81182 v 18.80409 h -6.08026 -0.48201 -23.51962 -6.56227 v -26.9111 h -4.355485 v 31.26077 h 10.917755 23.51962 0.48201 10.43575 v -23.15376 l -0.0407,-57.81182 V 632.0325 574.22648 539.56843 h 13.60074 24.00163 24.00163 10.43575 v -23.15377 -31.96927 z m 71.99909,0 v 4.35549 h 5.38338 v 26.85883 h -0.0407 v 57.85828 h 4.34968 v -56.34838 h 0.0406 v -32.72422 z m 120.00236,0 v 4.35549 h 5.37757 v 27.61378 18.80409 h -6.08606 -17.95042 l 0.0349,39.00773 v 18.79828 h -6.08026 -17.95622 v 38.30505 h 4.34968 v -33.94956 h 13.60654 10.43575 v -23.15377 l -0.0407,-34.65805 h 13.60074 10.43574 v -23.15377 -31.96927 z m 167.99982,0 v 4.35549 h 5.37757 v 26.90529 h 4.34968 V 484.44539 Z M 19.999597,508.30765 v 38.29924 h 17.956219 24.001633 22.811133 v -4.34968 H 61.957449 37.955816 24.349276 v -33.94956 z m 7.038466,0 v 31.26078 h 10.917753 24.001633 22.811133 v -4.34968 H 61.957449 37.955816 31.387742 v -26.9111 z m 448.957717,26.9111 v 0.75495 37.54429 h 4.35549 v -33.94956 h 13.60073 24.00163 22.81114 v -4.34968 H 517.95363 493.952 Z m 114.65963,0 v 4.34968 h 12.42185 v 34.65805 57.80602 57.81182 57.81182 25.84255 h -13.12453 -0.48201 -23.51963 -13.60073 v -33.94956 h -4.35549 v 38.29924 h 17.95622 23.51963 0.48201 17.47421 V 747.65614 689.84432 632.0325 574.22648 535.21875 Z m -107.62116,7.03846 v 0.75495 30.50583 h 4.35548 v -26.9111 h 6.56227 24.00163 22.81114 v -4.34968 H 517.95363 493.952 Z m 107.62116,0 v 4.34968 h 5.38338 v 26.86464 h -0.0406 v 58.56097 57.81182 58.56677 h 0.0406 v 18.04914 h -6.08606 -0.48201 -23.51963 -6.56226 v -26.9111 h -4.34968 v 31.26077 h 10.91194 23.51963 0.48201 10.43574 v -23.90871 h -0.0407 V 689.84432 632.0325 574.98143 h 0.0407 V 542.25721 Z M 284.00014,650.83658 v 0.75495 38.25279 l 0.0407,57.81182 v 18.80409 h -6.08607 -24.00163 -6.56226 v -26.9111 h -4.34968 v 31.26077 h 10.91194 24.00163 10.43575 v -23.15376 l -0.0406,-57.81182 v -34.65225 h 13.60073 22.81694 v -4.35549 h -22.81694 z m 90.658,0 v 4.35549 h 12.42184 v 33.94376 h 4.34968 v -38.29925 z m 101.33764,0 v 0.75495 38.25279 l 0.0406,57.81182 v 18.80409 h -6.08606 -23.99583 -6.56807 v -26.9111 h -4.34968 v 31.26077 h 10.91775 23.99583 10.43574 v -23.15376 l -0.0348,-57.81182 v -34.65225 h 13.60073 24.00163 22.81114 v -4.35549 H 517.95363 493.952 Z m -184.95717,7.04428 v 0.75495 31.96346 h 0.0406 l 0.0407,56.30192 h -0.0407 v 26.5975 h -13.12454 -24.00163 -13.60073 v -33.94956 h -4.35549 v 38.29924 h 17.95622 24.00163 17.47422 v -29.43728 h 0.0406 l -0.0406,-59.32172 h -0.0407 v -26.85884 h 6.56227 22.81694 v -4.34967 h -22.81694 z m 83.61953,0 v 4.34967 h 5.37757 v 26.9053 h 4.35549 v -31.25497 z m 108.37611,0 v 0.75495 31.96346 h 0.0407 l 0.0406,56.30192 h -0.0406 v 26.5975 H 469.95037 445.95454 432.348 v -33.94956 h -4.34968 v 38.29924 h 17.95622 23.99583 17.48002 v -29.43728 h 0.0407 l -0.0407,-59.32172 h -0.0407 v -26.85884 h 6.56227 24.00163 22.81114 v -4.34967 H 517.95363 493.952 Z M 331.9976,681.73731 v 38.29924 h 16.77152 v -4.34968 h -12.42184 v -33.94956 z m 7.03846,0 v 31.26077 h 9.73306 v -4.34968 h -5.37757 v -26.91109 z m 59.62371,26.91109 v 4.34968 h 12.41604 v 34.65806 25.84255 h -13.12453 -23.99583 -13.60654 v -33.94956 h -4.34968 v 38.29924 h 17.95622 23.99583 17.48001 V 747.65614 708.6484 Z m 0,7.03847 v 4.34968 h 5.37757 v 27.61959 18.80409 h -6.08606 -23.99583 -6.56807 v -26.9111 h -4.34968 v 31.26077 h 10.91775 23.99583 10.43574 v -23.15376 -31.96927 z"
|
||||||
|
transform="matrix(0.15572681,0,0,0.15572681,1.390094,49.845283)" />
|
||||||
|
<path
|
||||||
|
id="characters"
|
||||||
|
style="shape-inside:url(#rect835);display:inline;fill:#9e9e9e;fill-opacity:1;stroke:none;stroke-width:1.88976;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 12.76949,457.90016 v 0.94078 49.46671 h 24.948225 23.995826 24.001633 24.001636 23.99582 24.00164 24.00163 24.94242 V 457.90016 H 181.7159 157.71427 133.71263 109.71681 85.715174 61.713541 37.717715 Z m 215.99728,0 v 0.94078 49.46671 h 24.94822 24.94242 v -50.40749 h -24.94242 z m 120.00235,0 v 0.94078 49.46671 h 24.94242 24.94823 v -50.40749 h -24.94823 z m 96.00073,0 v 0.94078 49.46671 h 24.94242 24.00163 24.00163 23.99583 24.94822 V 457.90016 H 541.71136 517.71553 493.7139 469.71227 Z M 84.768582,515.70617 v 0.9466 49.4667 h 24.948228 24.94242 v -50.4133 h -24.94242 z m 143.998188,0 v 0.9466 49.4667 h 24.94822 24.94242 v -50.4133 h -24.94242 z m 96.00072,0 v 0.9466 49.4667 h 24.94823 24.94241 v -50.4133 h -24.94241 z m 96.00072,0 v 0.9466 49.4667 h 24.94242 24.94823 v -50.4133 h -24.94823 z m 119.99656,0 v 0.9466 49.4667 h 24.94822 24.94242 v -50.4133 H 565.71299 Z M 84.768582,573.51799 v 0.9466 49.46671 h 24.948228 24.94242 v -50.41331 h -24.94242 z m 143.998188,0 v 0.9466 49.46671 h 24.94822 24.00163 23.99583 24.00163 24.94242 v -50.41331 h -24.94242 -24.00163 -23.99583 -24.00163 z m 192.00144,0 v 0.9466 49.46671 h 24.94242 24.00164 24.00163 24.00163 23.99583 24.00163 24.94242 V 573.51799 H 565.71299 541.71136 517.71553 493.7139 469.71227 445.71063 Z M 84.768582,631.32982 v 0.94078 49.46671 h 24.948228 24.94242 v -50.40749 h -24.94242 z m 143.998188,0 v 0.94078 49.46671 h 24.94822 24.94242 v -50.40749 h -24.94242 z m 96.00072,0 v 0.94078 49.46671 h 24.94823 24.94241 v -50.40749 h -24.94241 z m 96.00072,0 v 0.94078 49.46671 h 24.94242 24.94823 v -50.40749 h -24.94823 z m 119.99656,0 v 0.94078 49.46671 h 24.94822 24.94242 V 631.32982 H 565.71299 Z M 84.768582,689.13583 v 0.94659 49.46671 h 24.948228 24.94242 v -50.4133 h -24.94242 z m 143.998188,0 v 0.94659 49.46671 h 24.94822 24.94242 v -50.4133 h -24.94242 z m 120.00235,0 v 0.94659 49.46671 h 24.94242 24.94823 v -50.4133 h -24.94823 z m 71.99909,0 v 0.94659 49.46671 h 24.94242 24.94823 v -50.4133 h -24.94823 z m 119.99656,0 v 0.94659 49.46671 h 24.94822 24.94242 v -50.4133 h -24.94242 z"
|
||||||
|
transform="matrix(0.15572681,0,0,0.15572681,1.390094,49.845283)" />
|
||||||
|
</g>
|
||||||
|
<defs
|
||||||
|
id="defs2">
|
||||||
|
<rect
|
||||||
|
x="3.6285765"
|
||||||
|
y="28.230612"
|
||||||
|
width="198.25528"
|
||||||
|
height="291.22577"
|
||||||
|
id="rect835" />
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<commands-component></commands-component>
|
||||||
|
<search-component></search-component>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
</div>
|
235
assets/templates/password_template.html
Normal file
|
@ -0,0 +1,235 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html class="staticrypt-html">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>/*[|template_title|]*/0</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
|
||||||
|
<!-- do not cache this page -->
|
||||||
|
<meta http-equiv="cache-control" content="max-age=0" />
|
||||||
|
<meta http-equiv="cache-control" content="no-cache" />
|
||||||
|
<meta http-equiv="expires" content="0" />
|
||||||
|
<meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" />
|
||||||
|
<meta http-equiv="pragma" content="no-cache" />
|
||||||
|
|
||||||
|
<link rel="icon" href="favicon.ico" sizes="any">
|
||||||
|
<link rel="icon" href="favicon.svg" type="image/svg+xml">
|
||||||
|
<link rel="manifest" href="manifest.webmanifest">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.staticrypt-page {
|
||||||
|
width: 360px;
|
||||||
|
padding: 8% 0 0;
|
||||||
|
margin: auto;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.staticrypt-form {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
max-width: 360px;
|
||||||
|
margin: 0 auto 100px;
|
||||||
|
padding: 45px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.staticrypt-form input[type="password"] {
|
||||||
|
outline: 0;
|
||||||
|
background: rgba(255,255,255,0.6);
|
||||||
|
color: rgba(0,0,0,0.8);
|
||||||
|
width: 100%;
|
||||||
|
border: 0;
|
||||||
|
margin: 0 0 15px;
|
||||||
|
padding: 15px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.staticrypt-form .staticrypt-decrypt-button {
|
||||||
|
text-transform: uppercase;
|
||||||
|
outline: 0;
|
||||||
|
background: #262626;
|
||||||
|
width: 100%;
|
||||||
|
border: 0;
|
||||||
|
padding: 15px;
|
||||||
|
font-size: 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
color: #b3b3b3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.staticrypt-form .staticrypt-decrypt-button:hover,
|
||||||
|
.staticrypt-form .staticrypt-decrypt-button:active,
|
||||||
|
.staticrypt-form .staticrypt-decrypt-button:focus {
|
||||||
|
filter: brightness(85%);
|
||||||
|
color: #ff4000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.staticrypt-html {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.staticrypt-body {
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
color: #b3b3b3;
|
||||||
|
background: #303030;
|
||||||
|
}
|
||||||
|
|
||||||
|
.staticrypt-logo {
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.staticrypt-content {
|
||||||
|
height: 100%;
|
||||||
|
font-family: monospace;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
.staticrypt-instructions {
|
||||||
|
margin-bottom: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.staticrypt-title {
|
||||||
|
font-size: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
label.staticrypt-remember {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
accent-color: #ff4000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.staticrypt-remember input[type="checkbox"] {
|
||||||
|
transform: scale(1.5);
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.staticrypt-spinner-container {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: #303030;
|
||||||
|
}
|
||||||
|
|
||||||
|
.staticrypt-spinner {
|
||||||
|
display: inline-block;
|
||||||
|
width: 2rem;
|
||||||
|
height: 2rem;
|
||||||
|
vertical-align: text-bottom;
|
||||||
|
border: 0.25em solid gray;
|
||||||
|
border-right-color: transparent;
|
||||||
|
border-radius: 50%;
|
||||||
|
-webkit-animation: spinner-border 0.75s linear infinite;
|
||||||
|
animation: spinner-border 0.75s linear infinite;
|
||||||
|
animation-duration: 0.75s;
|
||||||
|
animation-timing-function: linear;
|
||||||
|
animation-delay: 0s;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
animation-direction: normal;
|
||||||
|
animation-fill-mode: none;
|
||||||
|
animation-play-state: running;
|
||||||
|
animation-name: spinner-border;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spinner-border {
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="staticrypt-body">
|
||||||
|
<div id="staticrypt_loading" class="staticrypt-spinner-container">
|
||||||
|
<div class="staticrypt-spinner"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="staticrypt_content" class="staticrypt-content hidden">
|
||||||
|
<div class="staticrypt-page">
|
||||||
|
<div class="staticrypt-form">
|
||||||
|
<img class="staticrypt-logo" src="logo.svg">
|
||||||
|
<div class="staticrypt-instructions">
|
||||||
|
<p>/*[|template_instructions|]*/0</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form id="staticrypt-form" action="#" method="post">
|
||||||
|
<input
|
||||||
|
id="staticrypt-password"
|
||||||
|
type="password"
|
||||||
|
name="password"
|
||||||
|
placeholder="/*[|template_placeholder|]*/0"
|
||||||
|
autofocus
|
||||||
|
/>
|
||||||
|
|
||||||
|
<label id="staticrypt-remember-label" class="staticrypt-remember hidden">
|
||||||
|
<input id="staticrypt-remember" type="checkbox" name="remember" checked/>
|
||||||
|
/*[|template_remember|]*/0
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<input type="submit" class="staticrypt-decrypt-button" value="/*[|template_button|]*/0" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// these variables will be filled when generating the file - the template format is '/*[|variable_name|]*/0'
|
||||||
|
const staticryptInitiator = /*[|js_staticrypt|]*/ 0;
|
||||||
|
const templateError = "/*[|template_error|]*/0",
|
||||||
|
isRememberEnabled = /*[|is_remember_enabled|]*/ 0,
|
||||||
|
staticryptConfig = /*[|staticrypt_config|]*/ 0;
|
||||||
|
|
||||||
|
// you can edit these values to customize some of the behavior of StatiCrypt
|
||||||
|
const templateConfig = {
|
||||||
|
rememberExpirationKey: "staticrypt_expiration",
|
||||||
|
rememberPassphraseKey: "staticrypt_passphrase",
|
||||||
|
replaceHtmlCallback: null,
|
||||||
|
clearLocalStorageCallback: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
// init the staticrypt engine
|
||||||
|
const staticrypt = staticryptInitiator.init(staticryptConfig, templateConfig);
|
||||||
|
|
||||||
|
// try to automatically decrypt on load if there is a saved password
|
||||||
|
window.onload = async function () {
|
||||||
|
const { isSuccessful } = await staticrypt.handleDecryptOnLoad();
|
||||||
|
|
||||||
|
// if we didn't decrypt anything on load, show the password prompt. Otherwise the content has already been
|
||||||
|
// replaced, no need to do anything
|
||||||
|
if (!isSuccessful) {
|
||||||
|
// hide loading screen
|
||||||
|
document.getElementById("staticrypt_loading").classList.add("hidden");
|
||||||
|
document.getElementById("staticrypt_content").classList.remove("hidden");
|
||||||
|
document.getElementById("staticrypt-password").focus();
|
||||||
|
|
||||||
|
// show the remember me checkbox
|
||||||
|
if (isRememberEnabled) {
|
||||||
|
document.getElementById("staticrypt-remember-label").classList.remove("hidden");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// handle password form submission
|
||||||
|
document.getElementById("staticrypt-form").addEventListener("submit", async function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const password = document.getElementById("staticrypt-password").value,
|
||||||
|
isRememberChecked = document.getElementById("staticrypt-remember").checked;
|
||||||
|
|
||||||
|
const { isSuccessful } = await staticrypt.handleDecryptionOfPage(password, isRememberChecked);
|
||||||
|
|
||||||
|
if (!isSuccessful) {
|
||||||
|
alert(templateError);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
105
build.sh
Executable file
|
@ -0,0 +1,105 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# locale
|
||||||
|
export LC_ALL="C.UTF-8"
|
||||||
|
export TZ=:/etc/localtime
|
||||||
|
|
||||||
|
Help()
|
||||||
|
{
|
||||||
|
cat <<- 'HEREDOC'
|
||||||
|
|
||||||
|
Generate static website with encrypted code by staticrypt.
|
||||||
|
The first pass requires -t, -d and -u options, re-run it with -c option only.
|
||||||
|
|
||||||
|
Syntax: ./build.sh [-h] [Options...]
|
||||||
|
|
||||||
|
options:
|
||||||
|
-h Print this Help
|
||||||
|
-c Fetch options from ".staticrypt.conf"
|
||||||
|
-d "<path>" Desination webroot path or directory
|
||||||
|
-p "<password>" Password for decryption >= 12 characters
|
||||||
|
-s "<salt>" Salt string = 32 hexadecimal characters
|
||||||
|
-t "<string>" Title for the staticrypt form page
|
||||||
|
-u "<url>" Https or localhost Url for the destination root
|
||||||
|
|
||||||
|
Example: ./build.sh -u https://start.domain.tld -d static -t "STILDE - StartPage"
|
||||||
|
|
||||||
|
HEREDOC
|
||||||
|
}
|
||||||
|
|
||||||
|
cd "$(dirname $0)"
|
||||||
|
|
||||||
|
# install staticrypt package
|
||||||
|
if ! [[ -s ./node_modules/.bin/staticrypt ]]; then
|
||||||
|
npm install
|
||||||
|
fi
|
||||||
|
|
||||||
|
# options
|
||||||
|
while getopts ":hcd:p:s:t:u:" option; do
|
||||||
|
case $option in
|
||||||
|
h ) Help; exit 0 ;;
|
||||||
|
c ) _CONF=.staticrypt.conf ;;
|
||||||
|
d ) _DEST="${OPTARG}" ;;
|
||||||
|
p ) _PASS="${OPTARG}" ;;
|
||||||
|
s ) _SALT="${OPTARG}" ;;
|
||||||
|
t ) _TITLE="${OPTARG}" ;;
|
||||||
|
u ) _URL="${OPTARG}" ;;
|
||||||
|
\?) echo -e "Unknown option: -$OPTARG \n" >&2; Help; exit 1;;
|
||||||
|
: ) echo -e "Missing argument for -$OPTARG \n" >&2; Help; exit 1;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# use config file or input options
|
||||||
|
if [[ -z $_CONF ]]; then
|
||||||
|
if [[ -z $_DEST ]] || [[ -z $_URL ]] || [[ -z $_TITLE ]]; then
|
||||||
|
echo -e "Error: options -d and -u are mandatory.\n" >&2; Help; exit 1
|
||||||
|
fi
|
||||||
|
if [[ -z $_PASS ]]; then
|
||||||
|
_PASS=$(openssl rand -base64 12)
|
||||||
|
fi
|
||||||
|
if [[ -z $_SALT ]]; then
|
||||||
|
_SALT=$(openssl rand -hex 16)
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
_DEST=$(sed -n '/STATIC=/ s/STATIC=//p;' $_CONF | tr -d '\n')
|
||||||
|
_PASS=$(sed -n '/PASSWORD=/ s/PASSWORD=//p;' $_CONF | tr -d '\n')
|
||||||
|
_SALT=$(sed -n '/SALT=/ s/SALT=//p;' $_CONF | tr -d '\n')
|
||||||
|
_URL=$(sed -n '/URL=/ s/URL=//p;' $_CONF | tr -d '\n')
|
||||||
|
_TITLE=$(sed -n '/TITLE=/ s/TITLE=//p;' $_CONF | tr -d '\n')
|
||||||
|
fi
|
||||||
|
|
||||||
|
# create directories
|
||||||
|
mkdir -p --verbose assets/{root,source,templates} encrypted $_DEST
|
||||||
|
|
||||||
|
# generate an url hash for the decrypted form-less page
|
||||||
|
_URLHASH=$(STATICRYPT_PASSWORD=${_PASS} ./node_modules/.bin/staticrypt --config false --salt ${_SALT} --share)
|
||||||
|
|
||||||
|
# encrypt files & update config file
|
||||||
|
STATICRYPT_PASSWORD=${_PASS} \
|
||||||
|
./node_modules/.bin/staticrypt assets/source/ \
|
||||||
|
--config false \
|
||||||
|
--recursive true \
|
||||||
|
--remember 7 \
|
||||||
|
--salt ${_SALT} \
|
||||||
|
--template assets/templates/password_template.html \
|
||||||
|
--template-button "DECRYPTER" \
|
||||||
|
--template-instructions "Crypté avec StatiCrypt." \
|
||||||
|
--template-error "Mot de passe incorrect !" \
|
||||||
|
--template-placeholder "Mot de passe" \
|
||||||
|
--template-remember "Se souvenir de moi" \
|
||||||
|
--template-title "${_TITLE}" && \
|
||||||
|
cat <<- HEREDOC > .staticrypt.conf
|
||||||
|
STATIC=$_DEST
|
||||||
|
PASSWORD=$_PASS
|
||||||
|
SALT=$_SALT
|
||||||
|
URL=$_URL
|
||||||
|
TITLE=$_TITLE
|
||||||
|
DECRYPTURL=$_URL$_URLHASH
|
||||||
|
LOGOUTURL=$_URL#staticrypt_logout
|
||||||
|
HEREDOC
|
||||||
|
|
||||||
|
# copy assets and encrypted files to the webroot
|
||||||
|
cp -r assets/root/* $_DEST/
|
||||||
|
cp -r encrypted/source/* $_DEST/
|
||||||
|
|
||||||
|
cat .staticrypt.conf
|
20
package.json
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"name": "stilde",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Secure start page powered by staticrypt and tilde",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://git.tkapias.net/tkapias/stilde"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"startpage",
|
||||||
|
"homepage",
|
||||||
|
"minimal",
|
||||||
|
"encrypted"
|
||||||
|
],
|
||||||
|
"author": "Tomasz Kapias <tomasz@tkapias.net> (https://tkapias.net)",
|
||||||
|
"license": "UNLICENSED",
|
||||||
|
"dependencies": {
|
||||||
|
"staticrypt": "^3.3.0"
|
||||||
|
}
|
||||||
|
}
|