Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 765664aa51 | |||
| b4055d3579 | |||
| 5a9767e9e8 | |||
| 8bc6e9c0e0 | |||
| dbae26f095 | |||
| 502aba3da6 | |||
| c44527984d | |||
| f2ede4c018 | |||
| c4fb8b8a7c | |||
| 56ba01ad18 | |||
| 9c10b3b1d1 | |||
| 7a65841d2d | |||
| 7fd2b828ab | |||
| c7b90b7e7c | |||
| a6653cfb96 | |||
| 9cf2d70226 | |||
| e5f3e1714f | |||
| 4fe1c41b82 | |||
| c60e745665 | |||
| 8a6edd4f0e | |||
| c47aa209be | |||
| a56a594ff5 | |||
| 287f821e8c | |||
| 41443f4be9 | |||
| 9fae4b3b75 |
@@ -0,0 +1,41 @@
|
||||
name: Lint
|
||||
|
||||
# theta-env has no app code of its own to unit-test (it orchestrates the
|
||||
# proxy/sso-manager-node submodules) -- this checks the one thing that can
|
||||
# actually break silently: setup.sh and bootstrap.js.
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
push:
|
||||
branches-ignore:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
shellcheck:
|
||||
name: Shellcheck setup.sh
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Syntax check
|
||||
run: bash -n setup.sh
|
||||
|
||||
- name: Shellcheck
|
||||
run: shellcheck -S warning setup.sh
|
||||
|
||||
bootstrap-syntax:
|
||||
name: Syntax check bootstrap.js
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22.x
|
||||
|
||||
- name: Syntax check
|
||||
run: node --check bootstrap/bootstrap.js
|
||||
+4
-1
@@ -20,4 +20,7 @@ setup.env
|
||||
*.ldif
|
||||
|
||||
# Docker Compose runtime artifacts
|
||||
*.log
|
||||
*.log
|
||||
|
||||
# Jekyll build output (docs/ site) — generated, not committed.
|
||||
docs/_site
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project are documented here. Format loosely
|
||||
follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions
|
||||
correspond to git tags (`vX.Y.Z`). Entries here cover theta-env's own
|
||||
orchestration code; see each submodule's own `CHANGELOG.md`
|
||||
([proxy](https://github.com/theta42/proxy/blob/master/CHANGELOG.md),
|
||||
[sso-manager-node](https://github.com/theta42/sso-manager-node/blob/master/CHANGELOG.md))
|
||||
for what changed inside the apps it composes.
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [1.1.8] - 2026-07-17
|
||||
|
||||
### Bumped
|
||||
- sso-manager-node -> [v1.1.7](https://github.com/theta42/sso-manager-node/releases/tag/v1.1.7)
|
||||
|
||||
sso-manager-node:
|
||||
|
||||
### Changed
|
||||
- **Service accounts unified to one kind.** Removed the LDAP bind-only service account type (the Integrations → LDAP "Service Accounts" card, and its `/api/service-account` routes) -- every service account is now a real Unix/POSIX account with a UID, created from the new **Users → Service Accounts** tab. Email and password are both optional for service accounts; a blank password means no `userPassword` is set at all (the account simply can't bind).
|
||||
- **Added a `manager` field to every account.** Multi-valued (a list of usernames), defaults to whoever created the account (the admin who added it, or whoever sent the invite), and reassignable from the account's Edit form. Anyone listed as a manager can edit that account -- same fields an admin can (mobile, description, SSH key, date of birth, home directory, login shell, manager list) -- without needing `app_sso_admin`.
|
||||
- `homeDirectory` and `loginShell` are now editable from the Edit Profile form (previously view-only).
|
||||
|
||||
## [1.1.7] - 2026-07-16
|
||||
|
||||
### Bumped
|
||||
- proxy -> [v1.1.7](https://github.com/theta42/proxy/releases/tag/v1.1.7)
|
||||
- sso-manager-node -> [v1.1.6](https://github.com/theta42/sso-manager-node/releases/tag/v1.1.6)
|
||||
|
||||
Both: redesigned the GitHub Pages docs site to match each app's own look (dark navbar/footer, Bootstrap 5, Font Awesome) instead of the generic `jekyll-theme-cayman` theme, added a real cross-page nav, SEO (`jekyll-seo-tag` + `jekyll-sitemap`), and mobile-responsive layout. theta-env's own docs site got the same treatment in this release too (see below).
|
||||
|
||||
### Changed
|
||||
- theta-env's own docs site redesigned the same way -- dark navbar/footer using the shared theta42 logo (this repo has no app UI of its own), cross-page nav, SEO, mobile-responsive. `docs/index.md`'s "More docs" section removed (redundant with the new nav).
|
||||
- Added `docs/_site` to `.gitignore` (missing entirely before).
|
||||
|
||||
## [1.1.6] - 2026-07-16
|
||||
|
||||
### Bumped
|
||||
- proxy -> [v1.1.6](https://github.com/theta42/proxy/releases/tag/v1.1.6)
|
||||
|
||||
proxy: Hosts admin UI's Authentication tab radios (Off / Basic / SSO) had no shared `name`, so clicking one didn't uncheck the others. Added `name="auth_mode"` to restore standard exclusive radio-group behavior.
|
||||
|
||||
## [1.1.5] - 2026-07-16
|
||||
|
||||
### Bumped
|
||||
- proxy -> [v1.1.5](https://github.com/theta42/proxy/releases/tag/v1.1.5)
|
||||
- sso-manager-node -> [v1.1.5](https://github.com/theta42/sso-manager-node/releases/tag/v1.1.5)
|
||||
|
||||
Both: bumped `jq-repeat` 2.0.1 -> 2.1.0. proxy fixed real breakage from the removed `__setPut`/`__setTake` API (insert/remove row hooks in the admin UI); sso-manager-node fixed a stale-data flash in the edit-profile flow caused by `update()`'s new throttling.
|
||||
|
||||
## [1.1.4] - 2026-07-16
|
||||
|
||||
### Added
|
||||
- White-label support in both proxy and sso-manager-node -- `<title>`, navbar brand, and logo are now conf-driven (`conf.name`/`conf.logo`) instead of hardcoded. Closes [proxy#45](https://github.com/theta42/proxy/issues/45) and [sso-manager-node#6](https://github.com/theta42/sso-manager-node/issues/6).
|
||||
|
||||
### Fixed
|
||||
- sso-manager-node: the bundled default LDAP ppolicy had `pwdLockout: FALSE`, silently making "deactivate user" not actually block login. Fixed, with a drift-correction path for already-deployed instances.
|
||||
|
||||
### Bumped
|
||||
- proxy -> [v1.1.4](https://github.com/theta42/proxy/releases/tag/v1.1.4)
|
||||
- sso-manager-node -> [v1.1.4](https://github.com/theta42/sso-manager-node/releases/tag/v1.1.4)
|
||||
|
||||
## [1.1.3] - 2026-07-16
|
||||
|
||||
### Added
|
||||
- `CHANGELOG.md` (this file). Closes [#43](https://github.com/theta42/theta-env/issues/43).
|
||||
|
||||
### Bumped
|
||||
- proxy -> [v1.1.3](https://github.com/theta42/proxy/releases/tag/v1.1.3)
|
||||
- sso-manager-node -> [v1.1.3](https://github.com/theta42/sso-manager-node/releases/tag/v1.1.3)
|
||||
|
||||
## [1.1.2] - 2026-07-16
|
||||
|
||||
### Changed
|
||||
- `docs/index.md` (the published site's home page) never linked to `architecture.md`, `quickstart.md`, or `standalone.md` — added a "More docs" section so they're reachable from the site instead of only by direct URL.
|
||||
|
||||
### Bumped
|
||||
- proxy -> [v1.1.2](https://github.com/theta42/proxy/releases/tag/v1.1.2)
|
||||
- sso-manager-node -> [v1.1.2](https://github.com/theta42/sso-manager-node/releases/tag/v1.1.2)
|
||||
|
||||
## [1.1.1] - 2026-07-16
|
||||
|
||||
### Changed
|
||||
- `setup.sh` now pins `proxy` and `sso-manager-node` to their latest release tag (`vX.Y.Z`) instead of the tip of `master`. A rebuild now always lands on a tagged, versioned release of each app rather than whatever was most recently merged upstream.
|
||||
|
||||
### Bumped
|
||||
- proxy -> [v1.1.1](https://github.com/theta42/proxy/releases/tag/v1.1.1)
|
||||
- sso-manager-node -> [v1.1.1](https://github.com/theta42/sso-manager-node/releases/tag/v1.1.1)
|
||||
|
||||
## [1.1.0] - 2026-07-16
|
||||
|
||||
First tagged release. Establishes the `vX.Y.Z` tag convention going forward.
|
||||
|
||||
### Added
|
||||
- `setup.sh` now reports which submodules actually moved to a newer commit during an update, instead of updating silently.
|
||||
|
||||
### Bumped
|
||||
- proxy -> [v1.1.0](https://github.com/theta42/proxy/releases/tag/v1.1.0)
|
||||
- sso-manager-node -> [v1.1.0](https://github.com/theta42/sso-manager-node/releases/tag/v1.1.0)
|
||||
|
||||
[Unreleased]: https://github.com/theta42/theta-env/compare/v1.1.8...HEAD
|
||||
[1.1.8]: https://github.com/theta42/theta-env/compare/v1.1.7...v1.1.8
|
||||
[1.1.7]: https://github.com/theta42/theta-env/compare/v1.1.6...v1.1.7
|
||||
[1.1.6]: https://github.com/theta42/theta-env/compare/v1.1.5...v1.1.6
|
||||
[1.1.5]: https://github.com/theta42/theta-env/compare/v1.1.4...v1.1.5
|
||||
[1.1.4]: https://github.com/theta42/theta-env/compare/v1.1.3...v1.1.4
|
||||
[1.1.3]: https://github.com/theta42/theta-env/compare/v1.1.2...v1.1.3
|
||||
[1.1.2]: https://github.com/theta42/theta-env/compare/v1.1.1...v1.1.2
|
||||
[1.1.1]: https://github.com/theta42/theta-env/compare/v1.1.0...v1.1.1
|
||||
[1.1.0]: https://github.com/theta42/theta-env/releases/tag/v1.1.0
|
||||
@@ -471,7 +471,14 @@ theta-env/
|
||||
gitignored `./config/` (`sso-secrets.js` + `proxy-secrets.js`) and snapshots to
|
||||
the gitignored `./backups/` before each rebuild.
|
||||
|
||||
`./setup.sh` updates both submodules to the latest of their tracked remote
|
||||
branch before building, so each run builds current upstream — no manual
|
||||
`git submodule update --remote` needed. To lock to the pinned commits (offline
|
||||
rebuild, or a deliberate pin), run `SKIP_SUBMODULE_UPDATE=1 ./setup.sh`.
|
||||
`./setup.sh` updates both submodules to their latest `vX.Y.Z` release tag
|
||||
before building — not the tip of `master` — so each run builds the newest
|
||||
tagged release of each app, not whatever's most recently merged upstream. To
|
||||
lock to the pinned commits (offline rebuild, or a deliberate pin), run
|
||||
`SKIP_SUBMODULE_UPDATE=1 ./setup.sh`.
|
||||
|
||||
See [CHANGELOG.md](CHANGELOG.md) for what changed in each theta-env release
|
||||
(and each submodule's own `CHANGELOG.md` —
|
||||
[proxy](https://github.com/theta42/proxy/blob/master/CHANGELOG.md),
|
||||
[sso-manager-node](https://github.com/theta42/sso-manager-node/blob/master/CHANGELOG.md)
|
||||
— for what changed inside the apps themselves).
|
||||
+36
-4
@@ -1,9 +1,41 @@
|
||||
title: theta-env
|
||||
description: A unified, one-command SSO Manager + OIDC proxy stack for home labs and small businesses
|
||||
theme: jekyll-theme-cayman
|
||||
show_downloads: false
|
||||
description: A unified, one-command SSO Manager + OIDC proxy stack for home labs and small businesses.
|
||||
url: "https://theta42.github.io"
|
||||
baseurl: "/theta-env"
|
||||
logo: /assets/img/theta42.svg
|
||||
lang: en_US
|
||||
|
||||
plugins:
|
||||
- jekyll-seo-tag
|
||||
- jekyll-sitemap
|
||||
|
||||
github:
|
||||
repository_url: https://github.com/theta42/theta-env
|
||||
zip_url: https://github.com/theta42/theta-env/archive/refs/heads/master.zip
|
||||
tar_url: https://github.com/theta42/theta-env/archive/refs/heads/master.tar.gz
|
||||
repository_name: theta42/theta-env
|
||||
repository_name: theta42/theta-env
|
||||
|
||||
nav:
|
||||
- title: Home
|
||||
page: /
|
||||
icon: fa-house
|
||||
- title: Quickstart
|
||||
page: /quickstart.html
|
||||
icon: fa-rocket
|
||||
- title: Architecture
|
||||
page: /architecture.html
|
||||
icon: fa-sitemap
|
||||
- title: Standalone
|
||||
page: /standalone.html
|
||||
icon: fa-puzzle-piece
|
||||
- title: Changelog
|
||||
url: https://github.com/theta42/theta-env/blob/master/CHANGELOG.md
|
||||
icon: fa-list
|
||||
|
||||
defaults:
|
||||
- scope:
|
||||
path: ""
|
||||
type: "pages"
|
||||
values:
|
||||
layout: default
|
||||
image: /assets/img/theta42.svg
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<link rel="icon" type="image/svg+xml" href="{{ '/assets/img/theta42.svg' | relative_url }}">
|
||||
|
||||
{% seo title=false %}
|
||||
<title>{% if page.title %}{{ page.title }} · {% endif %}{{ site.title }}</title>
|
||||
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css">
|
||||
<link rel="stylesheet" href="{{ '/assets/css/style.css' | relative_url }}">
|
||||
</head>
|
||||
<body class="d-flex flex-column min-vh-100">
|
||||
|
||||
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
|
||||
<div class="container-fluid px-3">
|
||||
<a class="navbar-brand d-flex align-items-center" href="{{ '/' | relative_url }}">
|
||||
<img src="{{ '/assets/img/theta42.svg' | relative_url }}" height="28" class="me-2" alt="">
|
||||
{{ site.title }}
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navMain" aria-controls="navMain" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse justify-content-end" id="navMain">
|
||||
<ul class="navbar-nav">
|
||||
{% for item in site.nav %}
|
||||
<li class="nav-item">
|
||||
{% if item.page %}
|
||||
<a class="nav-link{% if page.url == item.page %} active{% endif %}" href="{{ item.page | relative_url }}">
|
||||
{% if item.icon %}<i class="fa-solid {{ item.icon }}"></i>{% endif %} {{ item.title }}
|
||||
</a>
|
||||
{% else %}
|
||||
<a class="nav-link" href="{{ item.url }}" target="_blank" rel="noopener">
|
||||
{% if item.icon %}<i class="fa-solid {{ item.icon }}"></i>{% endif %} {{ item.title }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main class="flex-grow-1" style="margin-top: 4.5rem;">
|
||||
<div class="container-fluid py-4 py-md-5">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-12 col-lg-10 col-xl-8">
|
||||
<div class="card shadow-lg">
|
||||
<div class="card-body p-4 p-md-5 site-content">
|
||||
{{ content }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="py-3 bg-dark text-light mt-auto">
|
||||
<div class="container-fluid d-flex flex-wrap justify-content-between align-items-center small gap-2 px-3">
|
||||
<span class="d-flex align-items-center gap-2">
|
||||
<a href="https://theta42.com" target="_blank" rel="noopener">
|
||||
<img width="40" src="{{ '/assets/img/theta42.svg' | relative_url }}" alt="theta42">
|
||||
</a>
|
||||
© {{ 'now' | date: '%Y' }} theta42 ·
|
||||
<a href="{{ site.github.repository_url }}/blob/master/LICENSE" target="_blank" rel="noopener" class="text-light">MIT License</a>
|
||||
</span>
|
||||
<span class="d-flex align-items-center gap-3">
|
||||
<a href="{{ site.github.repository_url }}" target="_blank" rel="noopener" class="text-light text-decoration-none">
|
||||
<i class="fa-brands fa-github"></i> GitHub
|
||||
</a>
|
||||
<a href="{{ site.github.repository_url }}/blob/master/CHANGELOG.md" target="_blank" rel="noopener" class="text-light text-decoration-none">
|
||||
<i class="fa-solid fa-list"></i> Changelog
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,6 +1,7 @@
|
||||
---
|
||||
layout: default
|
||||
title: Architecture
|
||||
description: How theta-env composes the SSO Manager and proxy submodules — the OIDC/LDAP wiring setup.sh generates from one domain.
|
||||
---
|
||||
|
||||
# Architecture
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
/* theta42 docs site — shares the in-app dark navbar/footer + card look
|
||||
(Bootstrap 5 + Font Awesome, same as the running apps) rather than a
|
||||
generic Jekyll theme. */
|
||||
|
||||
body {
|
||||
background-color: #f4f5f6;
|
||||
}
|
||||
|
||||
.navbar-brand img {
|
||||
filter: drop-shadow(0 0 2px rgba(0, 0, 0, .4));
|
||||
}
|
||||
|
||||
.navbar-nav .nav-link.active {
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Markdown content typography, scoped to the card body so it doesn't leak
|
||||
into the nav/footer. */
|
||||
.site-content h1:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.site-content h1,
|
||||
.site-content h2,
|
||||
.site-content h3 {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.site-content h2 {
|
||||
margin-top: 2.5rem;
|
||||
padding-bottom: .4rem;
|
||||
border-bottom: 1px solid #e9ecef;
|
||||
}
|
||||
|
||||
.site-content h3 {
|
||||
margin-top: 1.75rem;
|
||||
}
|
||||
|
||||
.site-content a {
|
||||
color: #a3671f;
|
||||
text-decoration-color: rgba(163, 103, 31, .35);
|
||||
}
|
||||
|
||||
.site-content a:hover {
|
||||
color: #8a5a16;
|
||||
}
|
||||
|
||||
.site-content pre {
|
||||
background-color: #212529;
|
||||
color: #f8f9fa;
|
||||
padding: 1rem 1.25rem;
|
||||
border-radius: .375rem;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.site-content code {
|
||||
color: #a3671f;
|
||||
background-color: #f4f0e8;
|
||||
padding: .15em .4em;
|
||||
border-radius: .25rem;
|
||||
font-size: .875em;
|
||||
}
|
||||
|
||||
.site-content pre code {
|
||||
color: inherit;
|
||||
background: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.site-content table {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 1.25rem 0;
|
||||
}
|
||||
|
||||
.site-content table th,
|
||||
.site-content table td {
|
||||
border: 1px solid #dee2e6;
|
||||
padding: .5rem .75rem;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.site-content table th {
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
.site-content blockquote {
|
||||
border-left: 4px solid #C59341;
|
||||
padding: .5rem 1rem;
|
||||
margin: 1.25rem 0;
|
||||
background-color: #f8f6f1;
|
||||
color: #495057;
|
||||
}
|
||||
|
||||
.site-content img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/* Screenshot grids in the markdown use width="49%" inline attrs for a
|
||||
two-up desktop layout -- stack them on narrow screens instead of
|
||||
squeezing to illegibility. */
|
||||
@media (max-width: 576px) {
|
||||
.site-content img[width] {
|
||||
width: 100% !important;
|
||||
margin-bottom: .75rem;
|
||||
}
|
||||
}
|
||||
|
||||
.site-content hr {
|
||||
margin: 2rem 0;
|
||||
border-top: 1px solid #e9ecef;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400" width="100%" height="100%">
|
||||
<defs>
|
||||
<linearGradient id="gold-grad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#C59341" />
|
||||
<stop offset="20%" stop-color="#E4B869" />
|
||||
<stop offset="40%" stop-color="#FBF0B9" />
|
||||
<stop offset="60%" stop-color="#DFB260" />
|
||||
<stop offset="80%" stop-color="#BC8837" />
|
||||
<stop offset="100%" stop-color="#A36F28" />
|
||||
</linearGradient>
|
||||
|
||||
<linearGradient id="text-grad" x1="0%" y1="100%" x2="100%" y2="0%">
|
||||
<stop offset="0%" stop-color="#FFFFFF" />
|
||||
<stop offset="40%" stop-color="#F5E3B5" />
|
||||
<stop offset="70%" stop-color="#D4A343" />
|
||||
<stop offset="100%" stop-color="#8A5A16" />
|
||||
</linearGradient>
|
||||
|
||||
<filter id="drop-shadow" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feDropShadow dx="0" dy="8" stdDeviation="6" flood-color="#000000" flood-opacity="0.4"/>
|
||||
</filter>
|
||||
</defs>
|
||||
|
||||
<g filter="url(#drop-shadow)">
|
||||
<g fill="url(#gold-grad)">
|
||||
<path d="M 200,40
|
||||
C 290,40 350,110 350,200
|
||||
C 350,290 290,360 200,360
|
||||
C 110,360 50,290 50,200
|
||||
C 50,110 110,40 200,40 Z
|
||||
M 200,75
|
||||
C 130,75 88,130 88,200
|
||||
C 88,270 130,325 200,325
|
||||
C 270,325 312,270 312,200
|
||||
C 312,130 270,75 200,75 Z"
|
||||
fill-rule="evenodd" />
|
||||
|
||||
<path d="M 88,190 L 140,190 C 140,190 142,210 140,210 L 88,210 Z" />
|
||||
|
||||
<path d="M 260,190 L 312,190 C 312,190 310,210 260,210 Z" />
|
||||
</g>
|
||||
|
||||
<text x="200" y="222"
|
||||
font-family="system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif"
|
||||
font-size="78"
|
||||
font-weight="900"
|
||||
fill="url(#text-grad)"
|
||||
text-anchor="middle"
|
||||
letter-spacing="-2">42</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
@@ -1,6 +1,7 @@
|
||||
---
|
||||
layout: default
|
||||
title: Home
|
||||
description: A unified, one-command SSO Manager + OIDC proxy stack for home labs and small businesses. Wires together a self-hosted identity provider and a reverse proxy with one setup.sh.
|
||||
---
|
||||
|
||||
# theta-env
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
---
|
||||
layout: default
|
||||
title: Quickstart
|
||||
description: Step-by-step first run for theta-env — prerequisites, setup.env, and bringing up the stack with ./setup.sh.
|
||||
---
|
||||
|
||||
# Quickstart Guide
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
User-agent: *
|
||||
Allow: /
|
||||
|
||||
Sitemap: https://theta42.github.io/theta-env/sitemap.xml
|
||||
@@ -1,6 +1,7 @@
|
||||
---
|
||||
layout: default
|
||||
title: Standalone
|
||||
description: Running the SSO Manager or the proxy on their own, without theta-env's orchestration.
|
||||
---
|
||||
|
||||
# Running each project standalone
|
||||
|
||||
+1
-1
Submodule proxy updated: 5333864e19...11f44176c0
@@ -146,32 +146,47 @@ then
|
||||
fi
|
||||
fi
|
||||
|
||||
# ── 1. Update submodules to latest, verify build contexts ─────────────────────
|
||||
# ── 1. Update submodules to their latest release tag, verify build contexts ───
|
||||
# Submodules track release tags (vX.Y.Z), not the tip of master -- so
|
||||
# "update" means "move to the newest tag", not "move to the newest commit".
|
||||
# `git submodule update --init --recursive` (no --remote) only clones a
|
||||
# missing submodule at its currently-pinned commit; it never advances it on
|
||||
# its own, so the per-submodule tag resolution below is what actually moves
|
||||
# proxy/sso-manager-node forward.
|
||||
if [[ "${SKIP_SUBMODULE_UPDATE:-0}" != "1" ]]; then
|
||||
if ! command -v git >/dev/null 2>&1; then
|
||||
die "git not found. Install git, or set SKIP_SUBMODULE_UPDATE=1 to build the pinned submodule commits."
|
||||
fi
|
||||
info "Updating submodules to latest (sso-manager-node, proxy)..."
|
||||
# Record each submodule's pinned commit before pulling so we can tell the
|
||||
# operator exactly what moved (or didn't) -- `git submodule update` itself
|
||||
# is quiet about this, and it's the only real "did anything change" signal
|
||||
# available to a script that isn't watching GitHub releases.
|
||||
declare -A SUBMODULE_BEFORE_REV=()
|
||||
for sm in sso-manager-node proxy; do
|
||||
[[ -d "$sm" ]] && SUBMODULE_BEFORE_REV["$sm"]="$(git -C "$sm" rev-parse HEAD 2>/dev/null || true)"
|
||||
done
|
||||
if ! git submodule update --init --remote --recursive 2>&1; then
|
||||
warn "git submodule update failed (offline?) — continuing with the currently checked-out code."
|
||||
else
|
||||
for sm in sso-manager-node proxy; do
|
||||
[[ -d "$sm" ]] || continue
|
||||
after_rev="$(git -C "$sm" rev-parse HEAD 2>/dev/null || true)"
|
||||
before_rev="${SUBMODULE_BEFORE_REV[$sm]:-}"
|
||||
if [[ -n "$before_rev" && -n "$after_rev" && "$before_rev" != "$after_rev" ]]; then
|
||||
info " ${sm}: updated ${before_rev:0:12} -> ${after_rev:0:12}"
|
||||
fi
|
||||
done
|
||||
if ! git submodule update --init --recursive 2>&1; then
|
||||
die "git submodule update --init failed. Run manually: git submodule update --init --recursive"
|
||||
fi
|
||||
|
||||
info "Updating submodules to their latest release tag (sso-manager-node, proxy)..."
|
||||
for sm in sso-manager-node proxy; do
|
||||
[[ -d "$sm" ]] || continue
|
||||
before_rev="$(git -C "$sm" rev-parse HEAD 2>/dev/null || true)"
|
||||
|
||||
if ! git -C "$sm" fetch --tags -q 2>&1; then
|
||||
warn " ${sm}: could not fetch tags (offline?) — staying on the current pin."
|
||||
continue
|
||||
fi
|
||||
|
||||
latest_tag="$(git -C "$sm" tag --list 'v*' --sort=-v:refname | head -n1)"
|
||||
if [[ -z "$latest_tag" ]]; then
|
||||
warn " ${sm}: no vX.Y.Z release tags found — staying on the current pin."
|
||||
continue
|
||||
fi
|
||||
|
||||
if ! git -C "$sm" checkout -q "$latest_tag" 2>&1; then
|
||||
warn " ${sm}: could not check out ${latest_tag} — staying on the current pin."
|
||||
continue
|
||||
fi
|
||||
|
||||
after_rev="$(git -C "$sm" rev-parse HEAD 2>/dev/null || true)"
|
||||
if [[ "$before_rev" != "$after_rev" ]]; then
|
||||
info " ${sm}: updated to ${latest_tag} (${before_rev:0:12} -> ${after_rev:0:12})"
|
||||
fi
|
||||
done
|
||||
else
|
||||
info "Skipping submodule update (SKIP_SUBMODULE_UPDATE=1)."
|
||||
fi
|
||||
@@ -543,7 +558,7 @@ backup_before_rebuild() {
|
||||
# Only prune real backup dirs — skip symlinks (a stray symlink could
|
||||
# point rm at an arbitrary tree) and non-dir entries.
|
||||
[[ -d "$BACKUP_DIR/$old" && ! -L "$BACKUP_DIR/$old" ]] || continue
|
||||
rm -rf "$BACKUP_DIR/$old" || true
|
||||
rm -rf "${BACKUP_DIR:?}/$old" || true
|
||||
removed=$((removed + 1))
|
||||
done < <(ls -1 "$BACKUP_DIR" 2>/dev/null | sort -r | tail -n +$((keep + 1)))
|
||||
[[ "$removed" -gt 0 ]] && info " pruned $removed old backup(s) (keeping $keep)."
|
||||
@@ -557,7 +572,8 @@ backup_before_rebuild
|
||||
# hash from inside the Docker build context. Resolve it on the host (where
|
||||
# the submodule DOES resolve correctly) and pass it in as a build arg; see
|
||||
# docker-compose.yml and sso-manager-node's Dockerfile.openldap.
|
||||
export SSO_GIT_COMMIT="$(git -C sso-manager-node rev-parse --short HEAD 2>/dev/null || echo unknown)"
|
||||
SSO_GIT_COMMIT="$(git -C sso-manager-node rev-parse --short HEAD 2>/dev/null || echo unknown)"
|
||||
export SSO_GIT_COMMIT
|
||||
info "Building + starting sso-manager (first run builds the image; this takes a while)..."
|
||||
"${COMPOSE[@]}" up -d --build sso-manager
|
||||
|
||||
@@ -614,7 +630,6 @@ BOOTSTRAP_OUT=$("${COMPOSE[@]}" exec -T sso-manager node /bootstrap/bootstrap.js
|
||||
|
||||
getval() { echo "$BOOTSTRAP_OUT" | grep -m1 "^$1=" | cut -d= -f2-; }
|
||||
CLIENT_ID=$(getval CLIENT_ID)
|
||||
CLIENT_SECRET=$(getval CLIENT_SECRET)
|
||||
ALREADY_CONFIGURED=$(getval ALREADY_CONFIGURED)
|
||||
[[ -n "$CLIENT_ID" ]] || die "bootstrap did not return CLIENT_ID:\n${BOOTSTRAP_OUT}"
|
||||
|
||||
@@ -626,7 +641,8 @@ fi
|
||||
|
||||
# ── 6. Start the proxy, wait for health ───────────────────────────────────────
|
||||
# PROXY_GIT_COMMIT: same reasoning as SSO_GIT_COMMIT above.
|
||||
export PROXY_GIT_COMMIT="$(git -C proxy rev-parse --short HEAD 2>/dev/null || echo unknown)"
|
||||
PROXY_GIT_COMMIT="$(git -C proxy rev-parse --short HEAD 2>/dev/null || echo unknown)"
|
||||
export PROXY_GIT_COMMIT
|
||||
info "Building + starting proxy (first run builds the image; this takes a while)..."
|
||||
"${COMPOSE[@]}" up -d --build proxy
|
||||
|
||||
|
||||
+1
-1
Submodule sso-manager-node updated: 8a13dee8ae...3ad817767a
Reference in New Issue
Block a user