auth: split dev-mode auth constructor and wire up dev-login/logout UI
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
Tests / Go tests (push) Successful in 13s

Squeamish about New()'s empty-domain-string sentinel for "dev mode, skip
OIDC discovery" - split into New (always makes a real OIDC discovery
call, all params required) and NewDev (no ctx/domain/credentials at all,
since none are used). main.go now branches on cfg.DevAuthEnabled to pick
the right constructor instead of main.go/config.go coordinating on when
it's safe to pass empty strings.

Also finishes out the dev-auth flow this enables: config.Load reads a
DEV_AUTH_ENABLED-aware env file and only requires Auth0 vars when dev
auth is off; a PORT config var replaces the hardcoded :8082; and the nav
UI (layout/index templates, ui router) points login/logout links at
/api/auth/dev-login and a new /api/auth/dev-logout route when dev auth
is enabled, so the whole login/logout loop works locally without a real
Auth0 app.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-20 00:36:55 -06:00
co-authored by Claude Sonnet 5
parent d2d67b43c1
commit ede7555d43
9 changed files with 275 additions and 64 deletions
+106 -10
View File
@@ -18,6 +18,7 @@
--text-xl--line-height: calc(1.75 / 1.25);
--text-3xl: 1.875rem;
--text-6xl: 3.75rem;
--text-6xl--line-height: 1;
--font-weight-semibold: 600;
--font-weight-bold: 700;
--radius-lg: var(--radius);
@@ -179,9 +180,18 @@
}
}
@layer utilities {
.invisible {
visibility: hidden;
}
.visible {
visibility: visible;
}
.absolute {
position: absolute;
}
.fixed {
position: fixed;
}
.relative {
position: relative;
}
@@ -319,6 +329,9 @@
.hidden {
display: none;
}
.inline {
display: inline;
}
.inline-block {
display: inline-block;
}
@@ -585,6 +598,10 @@
.font-display {
font-family: var(--display-family);
}
.text-6xl {
font-size: var(--text-6xl);
line-height: var(--tw-leading, var(--text-6xl--line-height));
}
.text-lg {
font-size: var(--text-lg);
line-height: var(--tw-leading, var(--text-lg--line-height));
@@ -617,12 +634,22 @@
.capitalize {
text-transform: capitalize;
}
.lowercase {
text-transform: lowercase;
}
.italic {
font-style: italic;
}
.underline {
text-decoration-line: underline;
}
.accent-secondary {
accent-color: var(--secondary);
}
.shadow {
--tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
.outline-1 {
outline-style: var(--tw-outline-style);
outline-width: 1px;
@@ -643,11 +670,6 @@
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
transition-duration: var(--tw-duration, var(--default-transition-duration));
}
.not-group-focus-within\:hidden {
&:not(*:is(:where(.group):focus-within *)) {
display: none;
}
}
.not-group-hover\:hidden {
&:not(*:is(:where(.group):hover *)) {
display: none;
@@ -656,11 +678,6 @@
display: none;
}
}
.not-group-focus\:hidden {
&:not(*:is(:where(.group):focus *)) {
display: none;
}
}
.not-open\:mb-\[1em\] {
&:not(*:is([open], :popover-open, :open)) {
margin-bottom: 1em;
@@ -1249,6 +1266,71 @@
syntax: "*";
inherits: false;
}
@property --tw-shadow {
syntax: "*";
inherits: false;
initial-value: 0 0 #0000;
}
@property --tw-shadow-color {
syntax: "*";
inherits: false;
}
@property --tw-shadow-alpha {
syntax: "<percentage>";
inherits: false;
initial-value: 100%;
}
@property --tw-inset-shadow {
syntax: "*";
inherits: false;
initial-value: 0 0 #0000;
}
@property --tw-inset-shadow-color {
syntax: "*";
inherits: false;
}
@property --tw-inset-shadow-alpha {
syntax: "<percentage>";
inherits: false;
initial-value: 100%;
}
@property --tw-ring-color {
syntax: "*";
inherits: false;
}
@property --tw-ring-shadow {
syntax: "*";
inherits: false;
initial-value: 0 0 #0000;
}
@property --tw-inset-ring-color {
syntax: "*";
inherits: false;
}
@property --tw-inset-ring-shadow {
syntax: "*";
inherits: false;
initial-value: 0 0 #0000;
}
@property --tw-ring-inset {
syntax: "*";
inherits: false;
}
@property --tw-ring-offset-width {
syntax: "<length>";
inherits: false;
initial-value: 0px;
}
@property --tw-ring-offset-color {
syntax: "*";
inherits: false;
initial-value: #fff;
}
@property --tw-ring-offset-shadow {
syntax: "*";
inherits: false;
initial-value: 0 0 #0000;
}
@property --tw-outline-style {
syntax: "*";
inherits: false;
@@ -1346,6 +1428,20 @@
--tw-skew-y: initial;
--tw-border-style: solid;
--tw-font-weight: initial;
--tw-shadow: 0 0 #0000;
--tw-shadow-color: initial;
--tw-shadow-alpha: 100%;
--tw-inset-shadow: 0 0 #0000;
--tw-inset-shadow-color: initial;
--tw-inset-shadow-alpha: 100%;
--tw-ring-color: initial;
--tw-ring-shadow: 0 0 #0000;
--tw-inset-ring-color: initial;
--tw-inset-ring-shadow: 0 0 #0000;
--tw-ring-inset: initial;
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-offset-shadow: 0 0 #0000;
--tw-outline-style: solid;
--tw-blur: initial;
--tw-brightness: initial;