feat: added express + vite app + oidc
All checks were successful
Publish Metadata Agent Image / build-and-push-image (push) Successful in 3m28s
Publish Web Player Image / build-and-push-image (push) Successful in 1m9s
Publish Server Image / build-and-push-image (push) Successful in 2m16s

This commit is contained in:
Boris Cherepanov
2026-03-19 15:06:32 +03:00
parent a7af27d064
commit cfcf6e4029
26 changed files with 6910 additions and 0 deletions

View File

@@ -0,0 +1,9 @@
PORT=3001
BASE_URL=http://localhost:3001
FRONTEND_ORIGIN=http://localhost:5173
SESSION_SECRET=super-long-random-secret
OIDC_ISSUER_BASE_URL=https://your-issuer.example.com
OIDC_CLIENT_ID=your-client-id
OIDC_CLIENT_SECRET=your-client-secret
OIDC_SCOPE="openid profile email"

24
furumi-node-player/server/.gitignore vendored Normal file
View File

@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

3355
furumi-node-player/server/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,28 @@
{
"name": "server",
"version": "1.0.0",
"type": "module",
"main": "dist/index.js",
"scripts": {
"dev": "tsx watch src/index.ts",
"build": "tsc -p tsconfig.json",
"start": "node dist/index.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"cors": "^2.8.6",
"dotenv": "^17.3.1",
"express": "^5.2.1",
"express-openid-connect": "^2.19.4"
},
"devDependencies": {
"@types/cors": "^2.8.19",
"@types/express": "^5.0.6",
"@types/node": "^25.5.0",
"tsx": "^4.21.0",
"typescript": "^5.9.3"
}
}

View File

@@ -0,0 +1,73 @@
import 'dotenv/config';
import cors from 'cors';
import express from 'express';
import { auth } from 'express-openid-connect';
const app = express();
const port = Number(process.env.PORT ?? 3001);
const frontendOrigin = process.env.FRONTEND_ORIGIN ?? 'http://localhost:5173';
const oidcConfig = {
authRequired: false,
auth0Logout: false,
secret: process.env.SESSION_SECRET ?? 'change-me-in-env',
baseURL: process.env.BASE_URL ?? `http://localhost:${port}`,
clientID: process.env.OIDC_CLIENT_ID ?? '',
issuerBaseURL: process.env.OIDC_ISSUER_BASE_URL ?? '',
clientSecret: process.env.OIDC_CLIENT_SECRET ?? '',
authorizationParams: {
response_type: 'code',
scope: process.env.OIDC_SCOPE ?? 'openid profile email',
},
};
if (!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',
);
}
app.use(
cors({
origin: frontendOrigin,
credentials: true,
}),
);
app.use(express.json());
app.use(auth(oidcConfig));
app.get('/api/health', (_req, res) => {
res.json({ ok: true });
});
app.get('/api/me', (req, res) => {
if (!req.oidc.isAuthenticated()) {
res.status(401).json({ authenticated: false });
return;
}
res.json({
authenticated: true,
user: req.oidc.user,
});
});
app.get('/api/login', (req, res) => {
res.oidc.login({
returnTo: frontendOrigin,
});
});
app.get('/api/logout', (req, res) => {
res.oidc.logout({
returnTo: frontendOrigin,
});
});
app.listen(port, () => {
console.log(`OIDC auth server listening on http://localhost:${port}`);
});

View File

@@ -0,0 +1,14 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"strict": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true,
"outDir": "dist",
"rootDir": "src"
},
"include": ["src"]
}