feat: added disable auth mode
All checks were successful
Publish Metadata Agent Image / build-and-push-image (push) Successful in 1m6s
Publish Web Player Image / build-and-push-image (push) Successful in 1m14s
Publish Server Image / build-and-push-image (push) Successful in 2m9s

This commit is contained in:
Boris Cherepanov
2026-03-19 15:47:21 +03:00
parent cfcf6e4029
commit 4f239c2546
5 changed files with 114 additions and 8 deletions

View File

@@ -8,6 +8,7 @@
## Запуск
1. Скопируй `server/.env.example` в `server/.env` и заполни OIDC параметры.
- Если нужно запустить без авторизации, поставь `DISABLE_AUTH=true` (OIDC параметры тогда не требуются).
2. В одном терминале:
- `cd server`
- `npm run dev`

View File

@@ -20,6 +20,32 @@
color: #5a6475;
}
.settings {
margin-bottom: 16px;
padding: 12px;
border: 1px solid #e6eaf2;
border-radius: 10px;
background: #f8fafc;
}
.toggle {
display: flex;
align-items: center;
gap: 10px;
color: #0f172a;
font-weight: 600;
}
.toggle input {
width: 18px;
height: 18px;
}
.hint {
margin: 10px 0 0;
color: #5a6475;
}
.btn {
display: inline-block;
text-decoration: none;

View File

@@ -7,14 +7,30 @@ type UserProfile = {
email?: string
}
const NO_AUTH_STORAGE_KEY = 'furumiNodePlayer.runWithoutAuth'
function App() {
const [loading, setLoading] = useState(true)
const [user, setUser] = useState<UserProfile | null>(null)
const [error, setError] = useState<string | null>(null)
const [runWithoutAuth, setRunWithoutAuth] = useState(() => {
try {
return window.localStorage.getItem(NO_AUTH_STORAGE_KEY) === '1'
} catch {
return false
}
})
const apiBase = useMemo(() => import.meta.env.VITE_API_BASE_URL ?? '', [])
useEffect(() => {
if (runWithoutAuth) {
setError(null)
setUser({ sub: 'noauth', name: 'No Auth' })
setLoading(false)
return
}
const loadMe = async () => {
try {
const response = await fetch(`${apiBase}/api/me`, {
@@ -40,7 +56,7 @@ function App() {
}
void loadMe()
}, [apiBase])
}, [apiBase, runWithoutAuth])
const loginUrl = `${apiBase}/api/login`
const logoutUrl = `${apiBase}/api/logout`
@@ -51,9 +67,37 @@ function App() {
<h1>OIDC Login</h1>
<p className="subtitle">Авторизация обрабатывается на Express сервере.</p>
<div className="settings">
<label className="toggle">
<input
type="checkbox"
checked={runWithoutAuth}
onChange={(e) => {
const next = e.target.checked
setRunWithoutAuth(next)
try {
if (next) window.localStorage.setItem(NO_AUTH_STORAGE_KEY, '1')
else window.localStorage.removeItem(NO_AUTH_STORAGE_KEY)
} catch {
// ignore
}
setLoading(true)
setUser(null)
}}
/>
<span>Запускать без авторизации</span>
</label>
</div>
{loading && <p>Проверяю сессию...</p>}
{error && <p className="error">Ошибка: {error}</p>}
{!loading && runWithoutAuth && (
<p className="hint">
Режим без авторизации включён. Для входа отключи настройку выше.
</p>
)}
{!loading && !user && (
<a className="btn" href={loginUrl}>
Войти через OIDC
@@ -75,9 +119,11 @@ function App() {
<strong>Email:</strong> {user.email}
</p>
)}
<a className="btn ghost" href={logoutUrl}>
Выйти
</a>
{!runWithoutAuth && (
<a className="btn ghost" href={logoutUrl}>
Выйти
</a>
)}
</div>
)}
</section>

View File

@@ -3,6 +3,9 @@ BASE_URL=http://localhost:3001
FRONTEND_ORIGIN=http://localhost:5173
SESSION_SECRET=super-long-random-secret
# Если true/1/on/yes — сервер стартует без OIDC и не требует авторизации.
DISABLE_AUTH=false
OIDC_ISSUER_BASE_URL=https://your-issuer.example.com
OIDC_CLIENT_ID=your-client-id
OIDC_CLIENT_SECRET=your-client-secret

View File

@@ -9,6 +9,10 @@ const app = express();
const port = Number(process.env.PORT ?? 3001);
const frontendOrigin = process.env.FRONTEND_ORIGIN ?? 'http://localhost:5173';
const disableAuth = ['1', 'true', 'yes', 'on'].includes(
String(process.env.DISABLE_AUTH ?? '').trim().toLowerCase(),
);
const oidcConfig = {
authRequired: false,
auth0Logout: false,
@@ -23,10 +27,10 @@ const oidcConfig = {
},
};
if (!oidcConfig.clientID || !oidcConfig.issuerBaseURL || !oidcConfig.clientSecret) {
if (!disableAuth && (!oidcConfig.clientID || !oidcConfig.issuerBaseURL || !oidcConfig.clientSecret)) {
// Keep a clear startup failure if OIDC is not configured.
throw new Error(
'OIDC config is missing. Set OIDC_ISSUER_BASE_URL, OIDC_CLIENT_ID, OIDC_CLIENT_SECRET in server/.env',
'OIDC config is missing. Set OIDC_ISSUER_BASE_URL, OIDC_CLIENT_ID, OIDC_CLIENT_SECRET in server/.env (or set DISABLE_AUTH=true)',
);
}
@@ -38,13 +42,27 @@ app.use(
);
app.use(express.json());
app.use(auth(oidcConfig));
if (!disableAuth) {
app.use(auth(oidcConfig));
}
app.get('/api/health', (_req, res) => {
res.json({ ok: true });
});
app.get('/api/me', (req, res) => {
if (disableAuth) {
res.json({
authenticated: false,
bypassAuth: true,
user: {
sub: 'noauth',
name: 'No Auth',
},
});
return;
}
if (!req.oidc.isAuthenticated()) {
res.status(401).json({ authenticated: false });
return;
@@ -57,17 +75,29 @@ app.get('/api/me', (req, res) => {
});
app.get('/api/login', (req, res) => {
if (disableAuth) {
res.status(204).end();
return;
}
res.oidc.login({
returnTo: frontendOrigin,
});
});
app.get('/api/logout', (req, res) => {
if (disableAuth) {
res.status(204).end();
return;
}
res.oidc.logout({
returnTo: frontendOrigin,
});
});
app.listen(port, () => {
console.log(`OIDC auth server listening on http://localhost:${port}`);
console.log(
`${disableAuth ? 'NO-AUTH' : 'OIDC auth'} server listening on http://localhost:${port}`,
);
});