Compare commits

...

15 Commits

Author SHA1 Message Date
wmantly 765664aa51 Merge pull request #60 from theta42/bump-sso-1.1.7
Bump sso-manager-node submodule pin to v1.1.7
2026-07-17 00:41:41 -04:00
wmantly b4055d3579 Bump sso-manager-node submodule pin to v1.1.7; update CHANGELOG
- sso-manager-node -> v1.1.7

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KDEx8ghuZR61pqPXc6da9C
2026-07-17 00:41:16 -04:00
wmantly 5a9767e9e8 Merge pull request #59 from theta42/bump-1.1.7
Bump submodule pins to v1.1.7/v1.1.6; backfill CHANGELOG.md
2026-07-16 20:50:25 -04:00
wmantly 8bc6e9c0e0 Bump submodule pins to v1.1.7/v1.1.6; backfill CHANGELOG.md
CHANGELOG.md had fallen behind theta-env's own tags -- entries
stopped at 1.1.3 despite v1.1.4/v1.1.5/v1.1.6 already being tagged
and released (each with real notes on GitHub, just never copied back
into this file). Backfilled 1.1.4-1.1.6 from the actual release
notes, then added 1.1.7 for this bump + the docs site redesign.

- proxy -> v1.1.7
- sso-manager-node -> v1.1.6
2026-07-16 20:49:59 -04:00
wmantly dbae26f095 Merge pull request #58 from theta42/redesign-docs-site
Redesign docs site: match the projects' own look, add SEO, mobile-ready
2026-07-16 20:21:05 -04:00
wmantly 502aba3da6 Redesign docs site: match the projects' own look, add SEO, mobile-ready
Same treatment as the proxy and sso-manager-node companion PRs. This
repo has no app UI of its own (it's a bash orchestrator), so both the
nav logo and favicon use the shared theta42.svg mark -- matching the
family look shown in its own screenshots (the SSO Manager/proxy
dashboards it stands up).

- New cross-page nav (Home/Quickstart/Architecture/Standalone/
  Changelog) -- replaces index.md's old "More docs" section, now
  redundant with the top nav.
- SEO: jekyll-seo-tag + jekyll-sitemap, per-page meta description,
  OG/Twitter card tags, canonical URLs, JSON-LD, sitemap.xml,
  robots.txt.
- Mobile: Bootstrap's responsive grid + collapsible navbar; the
  screenshot pair in index.md stacks to full-width below 576px.
- Added docs/_site to .gitignore (missing entirely before -- the
  other two repos already had it).

Verified with a real Jekyll build (jekyll/jekyll Docker image) +
Playwright: desktop and mobile (375px) screenshots, mobile nav
toggle, active-link highlighting, zero console/page errors, and
confirmed real SEO output (meta description, OG/Twitter tags,
canonical, JSON-LD, sitemap.xml, robots.txt) via curl against the
served site.
2026-07-16 20:20:42 -04:00
wmantly c44527984d Merge pull request #57 from theta42/bump-1.1.6
Bump proxy submodule pin to v1.1.6
2026-07-16 19:05:31 -04:00
wmantly f2ede4c018 Bump proxy submodule pin to v1.1.6
Picks up the Authentication tab radio-exclusivity fix.
2026-07-16 19:05:08 -04:00
wmantly c4fb8b8a7c Merge pull request #56 from theta42/bump-1.1.5
Bump proxy and sso-manager-node submodule pins to v1.1.5
2026-07-16 18:39:47 -04:00
wmantly 56ba01ad18 Bump proxy and sso-manager-node submodule pins to v1.1.5
Picks up the jq-repeat 2.1.0 upgrade in both apps.
2026-07-16 18:39:25 -04:00
wmantly 9c10b3b1d1 Merge pull request #55 from theta42/bump-1.1.4
Bump proxy and sso-manager-node submodule pins to v1.1.4
2026-07-16 17:48:36 -04:00
wmantly 7a65841d2d Bump proxy and sso-manager-node submodule pins to v1.1.4
Picks up: unified master-branch protection backed by real CI on all
3 repos, a ppolicy pwdLockout fix in sso-manager-node, and
white-label support (conf-driven title/logo) in both apps.
2026-07-16 17:48:13 -04:00
wmantly 7fd2b828ab Merge pull request #54 from theta42/add-ci
Add CI: shellcheck setup.sh, syntax-check bootstrap.js
2026-07-16 17:03:12 -04:00
wmantly c7b90b7e7c setup.sh: fix shellcheck findings (SC2115, SC2155 x2, SC2034)
- rm -rf "$BACKUP_DIR/$old" -> "${BACKUP_DIR:?}/$old": if BACKUP_DIR
  ever ended up empty, this was rm -rf /$old. Low practical risk
  (BACKUP_DIR is a hardcoded ./backups default), but cheap to harden.
- export FOO="$(...)" split into assign-then-export so a failing
  command substitution isn't masked by export's own exit status.
- Removed CLIENT_SECRET=$(getval CLIENT_SECRET): extracted from
  bootstrap's output but never used afterward (already written
  directly into proxy-secrets.js by bootstrap.js itself).
2026-07-16 17:02:29 -04:00
wmantly a6653cfb96 Add CI: shellcheck setup.sh, syntax-check bootstrap.js
theta-env has no app code of its own to unit-test (it orchestrates
the proxy/sso-manager-node submodules) -- this catches the one thing
that can actually break silently: setup.sh and bootstrap.js.
2026-07-16 17:00:27 -04:00
15 changed files with 402 additions and 21 deletions
+41
View File
@@ -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
View File
@@ -20,4 +20,7 @@ setup.env
*.ldif
# Docker Compose runtime artifacts
*.log
*.log
# Jekyll build output (docs/ site) — generated, not committed.
docs/_site
+57 -1
View File
@@ -10,6 +10,57 @@ 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
@@ -48,7 +99,12 @@ First tagged release. Establishes the `vX.Y.Z` tag convention going forward.
- 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.3...HEAD
[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
+36 -4
View File
@@ -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
+82
View File
@@ -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 }} &middot; {% 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>
&copy; {{ 'now' | date: '%Y' }} theta42 &middot;
<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
View File
@@ -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
+116
View File
@@ -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;
}
+51
View File
@@ -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 -9
View File
@@ -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
@@ -58,15 +59,6 @@ any time to converge the stack to `./config/`. For the full config reference,
architecture, and running each project standalone, see the
**[GitHub repository](https://github.com/theta42/theta-env)**.
## More docs
- **[Quickstart](quickstart.html)** — prerequisites and a step-by-step first run.
- **[Architecture](architecture.html)** — how the pieces fit together.
- **[Running each project standalone](standalone.html)** — using the SSO
Manager or the proxy on their own, without theta-env.
- **[Changelog](https://github.com/theta42/theta-env/blob/master/CHANGELOG.md)**
— what changed in each release.
## Related projects
- **[SSO Manager](https://theta42.github.io/sso-manager-node/)** — the OIDC
+1
View File
@@ -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
+4
View File
@@ -0,0 +1,4 @@
User-agent: *
Allow: /
Sitemap: https://theta42.github.io/theta-env/sitemap.xml
+1
View File
@@ -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: 1c29ba7206...11f44176c0
+5 -4
View File
@@ -558,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)."
@@ -572,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
@@ -629,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}"
@@ -641,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