mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-06 17:08:10 +00:00
bbcc4b59e45b72f8e2af1c07c8ed2c1740faa12d
18 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
865d792874 |
feat(pricing): collapse to two tiers (#1309)
* feat(pricing): collapse to two tiers (Community + Admiral) Collapse Sencho's pricing from three tiers (Community / Skipper / Admiral) to two: a generous free Community tier and a single paid Admiral tier. The Skipper tier is removed. Now free in Community: auto-heal, auto-update, scheduled operations, webhooks, notification routing, Fleet Actions and bulk operations, SSO preset providers (Google / GitHub / Okta), unlimited users with admin and viewer roles, and deploy safety (atomic deploys, auto-rollback, and one-click rollback). Admiral (paid) is focused on running and governing a fleet: blueprints, Fleet Secrets, deploy enforcement, vulnerability report export, audit log, host console, private registries, mesh networking, node cordon, managed cloud backup, LDAP / Active Directory SSO, and the advanced RBAC roles (deployer, node-admin, auditor) with per-resource scoped assignments. Internally the license variant distinction is removed so tier is binary (community / paid). License validation still verifies the Lemon Squeezy store and product before granting paid status. Docs and the contributor guide are updated to the two-tier model. * docs(pricing): correct licensing page to two-tier pricing and tidy stale tier wording The licensing docs page kept the old Admiral pricing plus a Founder Lifetime column and an Enterprise paragraph after the two-tier collapse. Update it to $12/month or $99/year, drop the lifetime and Enterprise content, and link to the pricing page for current pricing. Also fix stale "Skipper" wording in CLA.md, SUPPORT.md, one test title, and three test comments. Historical CHANGELOG entries and the retired-Skipper license-guard test are intentionally left as-is. * docs: align licensing and SSO pages with the two-tier model Correct the SSO overview so the Google, GitHub, and Okta presets read as available on every tier, matching the provider table; only LDAP and Active Directory require Sencho Admiral. Remove the lifetime-plan references from the licensing, settings, and troubleshooting pages so they reflect subscription-only Admiral pricing. * fix(rbac): omit scoped permissions from /me on the Community tier Scoped role assignments only take effect on the paid tier, but GET /api/permissions/me returned them unconditionally, so a downgraded instance with leftover assignments rendered per-resource affordances the API then rejected with 403. The endpoint now mirrors the permission middleware and includes scoped permissions only on the paid tier. Adds a regression test covering the downgrade case. * docs: use custom-pricing wording on the contact page The two-tier model has no Enterprise tier; reword the contact page's enterprise pricing/deals to custom pricing/deals so it does not imply a tier that no longer exists. |
||
|
|
4248ac0e72 |
fix(sso): surface config load, test, and removal errors in the SSO settings UI (#1265)
The SSO provider settings previously swallowed three failure paths: the provider-config load on mount, the connection test, and provider removal. A transient backend error, a tier-gate rejection, or a failed removal left the admin with no feedback at all. Each path now surfaces the backend message (or a clear fallback) through the standard error toast, matching the existing save handler. The connection-test handler also checks the response status before treating the body as a test result, so an API or authorization failure is no longer reported as a failed identity-provider connection. Adds component tests covering the non-ok and network-failure branches for each handler, including the unparseable-error-body fallback. |
||
|
|
1f8ce773ff |
feat(ui): hide paid features from community-tier dashboard (#891)
* feat(ui): hide paid features from community-tier dashboard Community installs render only the features they can use. Tier-locked sections, lock badges, upsell cards, and "Upgrade" buttons no longer appear anywhere except the License page in Settings, which is the single discoverable upgrade path. Concretely: - PaidGate and AdmiralGate now render null for non-qualifying tiers instead of upsell cards. - SectionGate (settings) hides tier-locked sections entirely. - Settings sidebar and command palette filter out items the operator cannot reach. - Configuration Status widget on the dashboard drops the Automation section for community and hides any locked rows in remaining sections. - Fleet > Status node cards drop locked summary rows. - Stack action menu, sidebar bulk bar, file upload / download, scan comparison, network topology toggle, node label picker all hide for community instead of showing disabled affordances or "Upgrade" literal text. - Removes tierUpsell, TierLockChip, and useDismissalState (no longer referenced). Backend tier guards remain authoritative; this changes UI discovery only. * test(e2e): assert upload control is absent in community tier The community-clean-ui change removes the "Upgrade to unlock upload" pill from the file explorer. Update the matching e2e assertion to verify the upload control is not rendered, instead of waiting for a pill that no longer exists. |
||
|
|
eead195529 |
feat(settings): dress the page to match the audit (#849)
* feat(settings): dress the page to match the audit (cyan rail, italic serif, two-column rows)
Brings the full-page Settings route into the Sencho voice. The page now
opens with a full-width PageMasthead (cyan rail, mono crumb, italic
serif title, contextual stat strip) above a sidebar and main-content
panel, each as a rounded-xl card inset on the dark background.
Sidebar drops the duplicate "Settings" header and the candy tier badges.
Group headers carry mono labels with visible/total counts; gated rows
get a neutral uppercase lock chip and dim. Active rows keep the cyan
2px rail.
Five new primitives (SettingsSection, SettingsField, SettingsCallout,
SettingsActions / SettingsPrimaryButton, TierLockChip) replace the
stacked label-input-help shadcn defaults and the per-section ad-hoc
chrome. AccountSection, AppearanceSection, LicenseSection, SystemSection,
NotificationsSection, DeveloperSection, AppStoreSection, AboutSection,
and SupportSection are migrated to the new layout. The list-driven
sections (Webhooks, Routing, Users, Labels, Security, CloudBackup,
ApiTokens, Registries, NodeManager, SSO) keep their list cards but get
the new chrome and primary CTAs.
Each section can publish contextual stats to the masthead via a small
context channel: 2FA state on Account, plan/trial/renews on License,
edited count on System, channel counts on Notifications, etc.
* refactor(settings): drop react-router-dom and align with DESIGN.md
The Settings page was the only surface using react-router-dom for sub-section
navigation. Every other primary view (Home, Fleet, Resources, App Store,
Schedules, etc.) drives view switching through a single activeView useState in
EditorLayout. This change removes the dependency end-to-end:
- App.tsx drops BrowserRouter
- EditorLayout adds 'settings' to the activeView union; SettingsPage renders
inside the same flex-1 overflow-y-auto p-6 wrapper as siblings
- UserProfileDropdown receives an onOpenSettings callback instead of
useNavigate. SettingsPage owns currentSection via props lifted to
EditorLayout, so cross-component navigation (openLabelManager,
onManageNodes, ConfigurationStatus rows) can route to a sub-section
- SettingsSidebar items become buttons (no more NavLink); SectionGate's
redirect-on-invisible falls back through SettingsPage's safeSection memo
- e2e/nodes.spec.ts updates the Nodes selector from link to button role
- react-router-dom removed from package.json + package-lock.json
The visual treatment is brought into alignment with frontend/DESIGN.md,
which was rewritten this week to be the normative extract of the audit:
- PageMasthead: title text-3xl → text-[22px] Section rung italic; kicker
11px → 10px Label rung; stat label tracking 0.22em → 0.18em; stat value
font-medium for mono Stat-rung family discipline
- SettingsField helper: mono → sans Body rung 14/22; success tone now uses
--success green (was incorrectly mapped to brand cyan)
- SettingsCallout: title tracking 0.18em; subtitle Body rung 14px; success
tone now genuinely uses --success green; new brand tone for promotional
callouts (Trial CTA, Admiral upgrade) that should read cyan
- SettingsActions: SettingsPrimaryButton renders mono uppercase tracked,
size sm by default. DESIGN §9.10 requires "small mono uppercase, cyan-
filled" for every Settings primary CTA
- TierLockChip: 9px → 10px Label rung floor
- SettingsSidebar: group header tracking 0.18em; ⌘K kbd 9px → 10px;
aside gains text-card-foreground transition-colors per §10 canonical
card class
- SettingsPage main panel: text-card-foreground transition-colors added;
uses h-full overflow-auto p-6 to mirror FleetView's wrapper rhythm
- Field rows, section headers, action rows now consume var(--density-*)
tokens with literal fallbacks so Settings respects the comfortable/
compact toggle
* fix(e2e): update mfa openAccountSettings to match settings redesign
Settings now opens to the Account section by default when accessed from
the profile dropdown, and the Account section no longer renders an h2
heading element. Update the openAccountSettings helper to open the
correct section and assert on the Password h3 heading that SettingsSection
renders instead.
* test(e2e): fix MFA enrolment assertion after settings redesign
The 2FA enrolment badge was replaced with a kicker/field pattern.
Assert on the 'enrolled' text that the new design renders instead of
the removed Enabled badge.
* test(e2e): fix low-backup-codes warning assertions after settings redesign
Update two assertions in the 'low backup codes warning' test that
referenced UI text removed in the settings redesign:
- '1 backup code remaining' -> '1 remaining' (SettingsField body text)
- 'Regenerate now' button -> callout subtitle text, which uniquely
identifies the zero-codes error card without hitting strict-mode
from two identically-labelled Regenerate buttons on the page
* test(e2e): navigate to root before re-opening settings for mock refresh
The settings redesign uses a nested full-page route. Navigating to the
same URL a second time does not remount the component, so AccountSection
retains cached MFA state and the 0-codes branch never fetches. A
page.goto('/') ensures full unmount before the second openAccountSettings
call, so the refreshed mock is actually hit.
* test(e2e): scroll zero-codes callout into view before asserting visibility
The callout sits below the Disable 2FA section in the MFA settings page
and is scrolled out of the clipped content area on initial render.
scrollIntoViewIfNeeded() brings it into the visible viewport before the
toBeVisible assertion.
* test(e2e): scroll Radix ScrollArea viewport for zero-codes callout assertion
The settings page wraps content in a Radix ScrollArea whose Root has
overflow:hidden, so the browser's native scrollIntoView cannot scroll
the inner viewport. Wait for the callout to attach (confirms mock data
loaded), then programmatically set scrollTop on the Radix viewport
element before asserting visibility.
* test(e2e): use toBeAttached for zero-codes callout to avoid Radix clip issue
The callout renders below the Disable 2FA section, outside the visible
clip area of the Radix ScrollArea Root (overflow:hidden) on a standard
viewport. Playwright's visibility check uses the clip intersection, so
toBeVisible() fails even after programmatic scroll. toBeAttached()
confirms the component rendered the warning card for backupCodesRemaining:0
without depending on the element's scroll position.
|
||
|
|
a502da54ee |
feat(sso): split SSO providers by delivery model across tiers (#754)
Custom OIDC stays on Community so self-hosters can wire any spec-compliant OIDC identity provider (Authelia, Keycloak, Authentik, Zitadel, and others). Google, GitHub, and Okta one-click presets move to Skipper. LDAP / Active Directory and scoped RBAC are Admiral-only. Backend enforces the split via a new requireTierForSsoProvider helper in middleware/tierGates.ts, applied after requireAdmin in all four ssoConfig mutation handlers. GET /sso/config (list) stays ungated so downgraded admins can still see previously-configured providers. Invalid provider ids now 400 before the tier check to avoid leaking tier information. Frontend adds a compact mode to PaidGate and AdmiralGate for inline list-item locks, and SSOSection reorders the provider cards as Custom OIDC > Google > GitHub > Okta > LDAP to reinforce the free-to-paid progression. Stale 'SSO is Admiral' copy in AdmiralGate, PaidGate, and the Admiral upgrade card on the License settings page has been replaced to reflect the new split. User-facing licensing, SSO, overview, quickstart, and security docs have been updated with the per-tier provider matrix. |
||
|
|
88ec71fcaa |
feat(ui): replace Switch with TogglePill per design audit (#687)
* chore: ignore local design-system references Adds frontend/DESIGN.md and .design-bundle/ to .gitignore so the design-system reference and the audit handoff bundle stay local to each contributor's machine. * feat(ui): replace Switch with TogglePill per design audit Adds a mono-uppercase ON/OFF pill that replaces the sliding Switch across every call site. The pill uses role="switch" plus aria-checked, tints success-green when on and neutral card-tone when off, and holds a stable 60px min-width so the label flip does not shift layout. It reinforces the tracked-mono uppercase pattern already used for kicker labels and table column headers, and echoes the UP/DN status language of the sidebar stack list. - Add TogglePill component (frontend/src/components/ui/toggle-pill.tsx) - Replace 17 Switch call sites across 10 files (settings sections, SSO providers, scheduled operations, network topology, resources, stack auto-heal) - Remove unused Switch wrapper and radix primitive - Drop the @radix-ui/react-switch dependency |
||
|
|
0bf061a745 |
feat(settings): group sections, add ⌘K search, scope breadcrumb (#680)
* feat(settings): group sections, add ⌘K search, scope breadcrumb Restructures the Settings Hub sidebar into four labelled groups (Identity, System, Alerts, Advanced), adds a ⌘K command palette for section search, and surfaces the active scope (global vs node-scoped) in the content breadcrumb. - New `settings/registry.ts` centralises group/item metadata, tier gates, glyph assignments, visibility rules, and keyword hints consumed by both the sidebar and the command palette - Cyan 2px left rail + gradient on the active sidebar item; mono-uppercase group headers; tier chips inline for locked items - Scoped ⌘K handler via onKeyDownCapture on DialogContent so the hub no longer hijacks the global sidebar shortcut while open - ScrollArea gains an opt-in `block` prop so the Nodes management table can overflow horizontally without Radix's default `display: table` wrapper clipping action buttons - Docs reference updated with the grouped sidebar, scope breadcrumb, and ⌘K walkthrough plus refreshed screenshots * refactor(settings): drop duplicate section headers, redesign system limits, always-visible tier chips - Remove redundant section titles in every settings page; the dialog header now owns the title and description - Rework System Limits into a compact row panel with inline-edit chips (warn state, focus ring) and an ON/OFF toggle pill - Show tier chips on sidebar and command palette whether locked or unlocked, so Skipper/Admiral scope is always legible - Keep right-aligned action buttons on pages that had a title+button header (Users, Labels, Nodes, API Tokens, Registries) * fix(settings): seed NumberChip draft on edit instead of via effect ESLint rule react-hooks/set-state-in-effect flagged the sync effect that mirrored the external value into local draft state. Replace it with a startEdit handler that seeds draft from value at click time, so the button path always reads value directly and no cascading render is triggered on prop change. * fix(settings): restore heading role and clean sidebar accessible names - Wrap the settings dialog title in an h2 so screen readers and E2E locators see a heading again after the in-section headers were removed - Mark the sidebar glyph aria-hidden so the button's accessible name is just the item label (fixes anchored name matchers) - Align the MFA E2E helper with the renamed Account section heading |
||
|
|
6890224903 |
fix(sso): harden Custom OIDC provider and SSO configuration (#630)
- Add Host header injection validation for OAuth callback URL derivation when SSO_CALLBACK_URL is not set (extracted into shared getSSOBaseUrl helper) - Add startup warning when OIDC providers are enabled without SSO_CALLBACK_URL - Add diagnostic logging for claim fallback, email changes on re-login, and admin seat limit enforcement (gated behind Developer Mode) - Add Custom OIDC environment variables to .env.example - Fix stale AdmiralGate comment in SSOSection.tsx - Fix .env.example section header referencing removed Admiral tier gate - Fix docs: correct Custom OIDC display name default, replace nonexistent DEBUG=true env var reference with Developer Mode toggle - Add tests for role enforcement (viewer 403), API token scope denial, OIDC claim edge cases, Custom OIDC test connection, callback error params - Refresh SSO settings screenshots |
||
|
|
7c6df0aa5d |
feat: add Custom OIDC provider and move SSO to Community tier (#626)
* feat: add Custom OIDC provider and move SSO to Community tier Add a generic Custom OIDC provider that works with any spec-compliant OIDC identity provider (Keycloak, Authentik, Authelia, Zitadel, KanIDM, Pocket ID, etc.) via standard discovery. Supports configurable claim mapping for User ID, Username, and Email fields to handle non-standard providers. Move all SSO functionality (LDAP and OIDC) from the Admiral tier to the Community tier so every user has access to identity provider integration. Backend: add oidc_custom to AuthProvider type, extend SSOService with claim mapping fields and env-var seeding, add oidc_custom to route validation, remove requireAdmiral guards from SSO config endpoints. Frontend: add Custom OIDC card with Display Name, Issuer URL, and claim mapping fields to SSOSection; add KeyRound icon on login page; remove AdmiralGate wrapper and lock icon from SSO settings nav. Tests: update tier guard expectations, add oidc_custom authorize/config/ provisioning tests and claim mapping coverage. All 992 tests pass. Docs: add Custom OIDC configuration reference, provider-specific setup examples, troubleshooting section, and updated screenshots. * fix: settings dialog close button overlap and combobox styling Reposition the close button in Settings Hub above the scroll area so it stays fixed when content scrolls. Increase dialog height to accommodate the growing number of setting sections. Fix combobox trigger styling to match Input component tokens (border-glass-border, bg-input) and eliminate the gap between trigger and dropdown list (top-full -mt-px). Apply the same fixes to multi-select-combobox for consistency. Add items-start to the Scopes/Default Role grid so the combobox aligns with the adjacent input field. Add showClose prop to DialogContent for consumers that need custom close button placement. Update SSO doc screenshots at 1920x900. |
||
|
|
1d89e8ce59 |
fix(sso): harden SSO with role sync, security fixes, design compliance, and test coverage (#564)
Rate-limit OIDC callback route and clear state cookie on all paths. Validate GitHub API responses and add server-side config validation. Sync SSO user roles on every login respecting seat limits. Add LDAP connection timeout, bind DN warning, and multiple entry logging. Replace Select with Combobox and apply card design tokens in SSOSection. Expose OIDC scopes field in settings UI. Fix hardcoded colors to use design system tokens. Add standard and diagnostic logging throughout SSO flow. Add tests for role sync, seat limits, LDAP escaping, and config validation. Remove unused login-form.tsx template. Update docs and screenshots for SSO feature. |
||
|
|
ee75811e25 |
feat(nodes): add capability-based node compatibility negotiation (#350)
* feat(nodes): add capability-based node compatibility negotiation Each Sencho instance now exposes /api/meta with its version and supported capabilities. When the user switches nodes, the frontend fetches this metadata and disables features the remote node doesn't support via a CapabilityGate overlay. Version is shown in the node switcher dropdown and connection test results. - Backend: CapabilityRegistry with static capability list and fetchRemoteMeta helper - Backend: /api/meta (public) and /api/nodes/:id/meta (auth) endpoints - Frontend: NodeContext enhanced with per-node meta caching (5min TTL) - Frontend: CapabilityGate component with typed Capability union - Frontend: 13 features wrapped with capability gates - Docs: node-compatibility.mdx + OpenAPI spec updates * fix(nodes): revert to require() for package.json version reading The static import fails in the Docker multi-stage build because the root package.json is not copied into the backend-builder stage. The require() call resolves at runtime when the file is available. |
||
|
|
d393d06885 |
Replace Sonner with custom Sera UI-inspired toast system (#296)
* refactor(ui): replace Sonner with custom Sera UI-inspired toast system Replace the Sonner toast library with a custom implementation inspired by Sera UI's glassmorphism design. The new system uses an external store pattern with useSyncExternalStore for React integration, keeping the same toast.success()/error()/warning() API so all 172 call sites required only an import path change. Key changes: - New toast-store.ts: singleton store with identical API to Sonner - New toast.tsx: Sera UI-faithful Notification component with Framer Motion animations, frosted glass (backdrop-blur-xl), type gradient overlays, animated progress bar (green→blue→sky gradient), and hover:scale-105 - Removed sonner and next-themes dependencies - Rewired all 19 consumer files to import from the new store * fix(ui): resolve ESLint errors in toast system - Use const for listeners Set (prefer-const) - Initialize startRef with 0 instead of Date.now() to satisfy react-hooks/purity rule, set actual value inside useEffect |
||
|
|
7637091e84 |
feat(ui): glassmorphism redesign with settings decomposition (#274)
* feat(ui): add glassmorphism design tokens and utility classes Introduce glass design system foundation: translucent oklch color variables for both light and dark themes, glass/glass-border/glass-highlight tokens, semantic status colors (success/warning/info), .glass and .glass-strong utility classes with backdrop-filter, reduced shadow values, and standardized spring animation presets in lib/motion.ts. * feat(ui): apply glass treatment to core components Update card, dialog, input, button, popover, sheet, tooltip, dropdown-menu, context-menu, select, alert-dialog, and tabs components with glassmorphism styling: translucent backgrounds via new CSS variables, backdrop-blur layers, glass-border luminous edges, and glass-highlight hover states. * refactor(settings): decompose Settings Modal into section components Extract 10 inline sections from the 1,987-line SettingsModal into dedicated files under components/settings/. Introduce section registry pattern replacing 14 conditional blocks. Add shared types, sidebar navigation grouping with separators, glass treatment on sidebar and nav buttons, and responsive modal height. SettingsModal shell shrinks to ~380 lines. * refactor(ui): unify all tabs to animate-ui TabsHighlight with glass styling Migrate 4 tab instances (EditorLayout, FleetView, ResourcesView, NotificationsSection) from inconsistent patterns (manual layoutId, underline border-b-2, default fade) to the shared TabsHighlight primitive with glass-highlight indicator and springs.snappy transition. Standardize EditorLayout nav highlight spring config, apply glass-highlight to sidebar stack list hover/active states, and update mobile nav styling. * refactor(ui): migrate hardcoded colors to semantic CSS variables Replace hardcoded Tailwind color classes across ~19 component files with semantic CSS variable classes: emerald/green to success, orange/amber to warning, blue to info. Preserves brand/decorative colors (Crown amber, Admiral blue). Enables consistent theming of status indicators across the entire application. * refactor(ui): Linear dark precision aesthetic — solid surfaces, depth cues, text hierarchy Replace glassmorphism with Linear.app-inspired design: solid surface tokens (card #111111, sidebar #0d0d0d, root #0a0a0a), backdrop-blur restricted to floating overlays only (blur(10px) saturate(1.15)), desaturated teal accent, font-weight 500 everywhere, monochrome chart palette, and three depth cues: root ambient glow, luminous card top-edge, steep text brightness ramp. * refactor(ui): precision polish — fix muddy dark, snowblind light, add design anchors - Replace 34 hardcoded rgba values with theme-aware stat-* CSS tokens - Fix light theme: solid white cards, off-white background, readable text - Add card-border tokens with sharper directional lighting (top edge 2x) - Add chart-grid/chart-tick tokens for theme-aware axis rendering - Upgrade body glow: teal-tinted (dark), warm amber (light) - Terminal-inspired sidebar: monospaced UP/DN status codes, Geist Mono - Add tabular-nums to stat values to prevent layout jitter - Light mode cards get shadow-sm for depth against off-white background * refactor(ui): Linear materiality pass — ghosted nav, translucent sidebar, font unity - De-escalate Delete button from solid destructive to ghost with hover fill - Make sidebar translucent (80% opacity + backdrop-blur) so body glow bleeds through - Bump dark nav accent to 0.07 for ghosted backlit selection - Unify all terminal/editor fonts to Geist Mono (was JetBrains/Consolas mix) - Add Monaco editor fontFamily for YAML/env editing consistency - Add threshold-based color to Host RAM and Host Disk stat values (warn/crit) * refactor(ui): material simulation — inherent depth, layer separation, recessed terminal - Bump dark background 0.065→0.08, card surfaces 0.10→0.12 for 4% layer separation - Add card-bevel token (inset top shimmer) for permanent structural depth - Add button-inner-glow token for physical key feel on outline buttons - Recess terminal with inset shadow and dimmed label - Reduce action icon strokeWidth to 1.5 for refined industrial feel - Add teal LED backlight bar on active nav item via blur pseudo-element * fix(ui): parse usagePercent string to number for getValueColor usagePercent is typed as string in SystemStats but getValueColor expects number, causing TS2345 in CI builds. |
||
|
|
f4428a394c |
refactor: use nautical icons for Skipper and Admiral tiers (#257)
* refactor: use nautical icons for Skipper and Admiral tiers Replace Crown/Users with Compass (Skipper) and ShipWheel (Admiral) across TierBadge, ProGate, AdmiralGate, and SettingsModal upgrade cards. * feat(sso): add Admiral tier badge next to SSO Authentication title |
||
|
|
c328b7f49a |
refactor: rename Personal Pro to Skipper and Team Pro to Admiral (#256)
Align paid tier names with Sencho's nautical identity. Internal variant
values ('personal'/'team') remain unchanged in code, database, and
Lemon Squeezy integration — only user-facing display names updated.
- Backend: requireTeamPro → requireAdmiral, TEAM_PRO_REQUIRED → ADMIRAL_REQUIRED
- Frontend: TeamProGate.tsx → AdmiralGate.tsx, TierBadge labels updated
- Website: PricingSection tier names and nautical descriptions
- Docs: all 11 affected pages renamed, nautical footnote added to licensing
|
||
|
|
31e1795af0 |
feat(scheduled-ops): add scheduled operations for Team Pro users (#231)
Adds the ability to schedule recurring Docker operations (stack restarts, fleet snapshots, system prunes) via cron expressions with full execution history logging. Includes Run Now for on-demand execution. |
||
|
|
8d48b0abff |
fix: gate SSO and Audit behind Team Pro license tier (#213)
SSO settings tab and content were visible to Personal Pro users despite being a Team Pro-only feature. Added TeamProGate component that checks both isPro and variant === 'team', and hid the SSO nav button for non-Team Pro users. Audit was already correctly gated in EditorLayout. |
||
|
|
bd4008f509 |
feat: SSO & LDAP authentication for Team Pro (#209)
* feat: SSO & LDAP authentication for Team Pro Add SSO integration allowing Team Pro users to authenticate via LDAP/Active Directory, Google, GitHub, and Okta identity providers. SSO works alongside password authentication with auto-provisioning and role mapping. - LDAP bind+search authentication with group-based role mapping - OIDC/OAuth2 flows with PKCE and CSRF protection for Google, GitHub, Okta - Auto-provisioning: first SSO login creates a Sencho account automatically - Role mapping via LDAP group membership or OIDC JWT claims - SSO settings UI in Settings → SSO with per-provider config and test connection - SSO login buttons on login page with LDAP toggle - Environment variable seeding for infrastructure-as-code workflows - Secrets encrypted at rest via CryptoService (AES-256-GCM) - Seat limit enforcement during auto-provisioning - Full documentation: feature docs, quickstart guides, env var reference * fix: resolve ESLint errors in SSO feature - Remove unnecessary escape characters in regex character classes - Remove unused `issuer` variable from OIDC callback handler - Fix setState-in-effect lint error in Login.tsx by using useState initializer - Suppress set-state-in-effect for SSOSection fetch pattern (matches existing codebase convention) |