mirror of
https://github.com/Smaug123/PulumiConfig
synced 2025-10-05 08:38:41 +00:00
@@ -95,6 +95,7 @@ type Address =
|
|||||||
|
|
||||||
type WellKnownSubdomain =
|
type WellKnownSubdomain =
|
||||||
| Nextcloud
|
| Nextcloud
|
||||||
|
| Apps
|
||||||
| Gitea
|
| Gitea
|
||||||
| Radicale
|
| Radicale
|
||||||
| Rss
|
| Rss
|
||||||
@@ -106,18 +107,20 @@ type WellKnownSubdomain =
|
|||||||
|
|
||||||
override this.ToString () =
|
override this.ToString () =
|
||||||
match this with
|
match this with
|
||||||
| Nextcloud -> "nextcloud"
|
| WellKnownSubdomain.Nextcloud -> "nextcloud"
|
||||||
| Gitea -> "gitea"
|
| WellKnownSubdomain.Apps -> "apps"
|
||||||
| Radicale -> "calendar"
|
| WellKnownSubdomain.Gitea -> "gitea"
|
||||||
| Rss -> "rss"
|
| WellKnownSubdomain.Radicale -> "calendar"
|
||||||
| Grafana -> "grafana"
|
| WellKnownSubdomain.Rss -> "rss"
|
||||||
| Woodpecker -> "woodpecker"
|
| WellKnownSubdomain.Grafana -> "grafana"
|
||||||
| WoodpeckerAgent -> "woodpecker-agent"
|
| WellKnownSubdomain.Woodpecker -> "woodpecker"
|
||||||
| PureGym -> "puregym"
|
| WellKnownSubdomain.WoodpeckerAgent -> "woodpecker-agent"
|
||||||
| Whisper -> "whisper"
|
| WellKnownSubdomain.PureGym -> "puregym"
|
||||||
|
| WellKnownSubdomain.Whisper -> "whisper"
|
||||||
|
|
||||||
static member Parse (s : string) =
|
static member Parse (s : string) =
|
||||||
match s with
|
match s with
|
||||||
|
| "apps" -> WellKnownSubdomain.Apps
|
||||||
| "nextcloud" -> WellKnownSubdomain.Nextcloud
|
| "nextcloud" -> WellKnownSubdomain.Nextcloud
|
||||||
| "gitea" -> WellKnownSubdomain.Gitea
|
| "gitea" -> WellKnownSubdomain.Gitea
|
||||||
| "calendar" -> WellKnownSubdomain.Radicale
|
| "calendar" -> WellKnownSubdomain.Radicale
|
||||||
|
32
PulumiWebServer/Nix/apps/apps.nix
Normal file
32
PulumiWebServer/Nix/apps/apps.nix
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
options = {
|
||||||
|
services.apps-config = {
|
||||||
|
domain = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
example = "example.com";
|
||||||
|
description = lib.mdDoc "Top-level domain to configure";
|
||||||
|
};
|
||||||
|
subdomain = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
example = "apps";
|
||||||
|
description = lib.mdDoc "Subdomain in which to put apps";
|
||||||
|
};
|
||||||
|
port = lib.mkOption {
|
||||||
|
type = lib.types.port;
|
||||||
|
description = lib.mdDoc "App server localhost port";
|
||||||
|
default = 9521;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = {
|
||||||
|
services.nginx.virtualHosts."${config.services.apps-config.subdomain}.${config.services.apps-config.domain}" = {
|
||||||
|
forceSSL = true;
|
||||||
|
enableACME = true;
|
||||||
|
root = ./static;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
12
PulumiWebServer/Nix/apps/static/index.html
Normal file
12
PulumiWebServer/Nix/apps/static/index.html
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<h1>Apps</h1>
|
||||||
|
<p>This is a collection of single-page applications, mostly vomited out by Claude to solve small tasks.</p>
|
||||||
|
<ul>
|
||||||
|
<li><a href="/middle_word.html">Compute the number of words in a string and the middle word.</a></li>
|
||||||
|
<li><a href="/sha256sum.html">Compute SHA256sums, as one might wish to do to verify someone's precommitment to a piece of text.</a></li>
|
||||||
|
</ul>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
25
PulumiWebServer/Nix/apps/static/middle_word.html
Normal file
25
PulumiWebServer/Nix/apps/static/middle_word.html
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<textarea id="input" rows="10" cols="50"></textarea><br>
|
||||||
|
<button onclick="analyzeText()">Ok</button>
|
||||||
|
<div id="result"></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function analyzeText() {
|
||||||
|
const text = document.getElementById('input').value;
|
||||||
|
const words = text.trim().split(' ').filter(word => word.length > 0);
|
||||||
|
const count = words.length;
|
||||||
|
const result = `Word count: ${count}`;
|
||||||
|
|
||||||
|
if (count % 2 === 1) {
|
||||||
|
const middleWord = words[Math.floor(count/2)];
|
||||||
|
document.getElementById('result').textContent =
|
||||||
|
`${result}\nMiddle word: ${middleWord}`;
|
||||||
|
} else {
|
||||||
|
document.getElementById('result').textContent = result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
95
PulumiWebServer/Nix/apps/static/sha256sum.html
Normal file
95
PulumiWebServer/Nix/apps/static/sha256sum.html
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Base64 Decoder and SHA256 Calculator</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 20px auto;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
.input-group {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
textarea {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 100px;
|
||||||
|
padding: 8px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
padding: 8px 16px;
|
||||||
|
background-color: #4CAF50;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
button:hover {
|
||||||
|
background-color: #45a049;
|
||||||
|
}
|
||||||
|
#hashOutput {
|
||||||
|
font-family: monospace;
|
||||||
|
padding: 8px;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="base64Input">Base64 Input:</label>
|
||||||
|
<textarea id="base64Input" placeholder="Enter base64 encoded text here"></textarea>
|
||||||
|
<button onclick="decodeBase64()">Decode Base64</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="textInput">Text Input:</label>
|
||||||
|
<textarea id="textInput" placeholder="Enter text or see decoded base64 here"></textarea>
|
||||||
|
<button onclick="calculateSHA256()">Calculate SHA256</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="hashOutput">SHA256 Hash:</label>
|
||||||
|
<div id="hashOutput"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function decodeBase64() {
|
||||||
|
try {
|
||||||
|
const base64Input = document.getElementById('base64Input').value;
|
||||||
|
const decoded = atob(base64Input);
|
||||||
|
document.getElementById('textInput').value = decoded;
|
||||||
|
} catch (error) {
|
||||||
|
alert('Invalid base64 input: ' + error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function calculateSHA256() {
|
||||||
|
try {
|
||||||
|
const text = document.getElementById('textInput').value;
|
||||||
|
const encoder = new TextEncoder();
|
||||||
|
const data = encoder.encode(text);
|
||||||
|
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
|
||||||
|
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
||||||
|
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
|
||||||
|
document.getElementById('hashOutput').textContent = hashHex;
|
||||||
|
} catch (error) {
|
||||||
|
alert('Error calculating hash: ' + error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@@ -7,6 +7,7 @@
|
|||||||
in {
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
./sops.nix
|
./sops.nix
|
||||||
|
./apps/apps.nix
|
||||||
./radicale/radicale-config.nix
|
./radicale/radicale-config.nix
|
||||||
./gitea/gitea-config.nix
|
./gitea/gitea-config.nix
|
||||||
./miniflux/miniflux.nix
|
./miniflux/miniflux.nix
|
||||||
@@ -43,6 +44,8 @@ in {
|
|||||||
services.prometheus-config.domain-exporter-domains = [userConfig.domain];
|
services.prometheus-config.domain-exporter-domains = [userConfig.domain];
|
||||||
services.puregym-config.domain = userConfig.domain;
|
services.puregym-config.domain = userConfig.domain;
|
||||||
services.puregym-config.subdomain = "puregym";
|
services.puregym-config.subdomain = "puregym";
|
||||||
|
services.apps-config.subdomain = "apps";
|
||||||
|
services.apps-config.domain = userConfig.domain;
|
||||||
# services.whisper-config.domain = userConfig.domain;
|
# services.whisper-config.domain = userConfig.domain;
|
||||||
# services.whisper-config.subdomain = "whisper";
|
# services.whisper-config.subdomain = "whisper";
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user