This commit is contained in:
Primakov Alexandr Alexandrovich
2024-11-04 18:47:17 +03:00
parent 10dc3e5ffe
commit ef35a8aa6c
12 changed files with 3819 additions and 0 deletions

8
server/.serverrc.js Normal file
View File

@@ -0,0 +1,8 @@
const path = require('path');
module.exports = {
dataPath: path.resolve(__dirname, 'data'),
maxLogCount: 3,
mailStepTimer: 3000,
protocol: 'http',
}

View File

@@ -0,0 +1,40 @@
const assignParam = (dev, prod) =>
process.env.NODE_ENV !== 'production' ? dev : prod
const parseToken = (req, res, next) => {
req.isAdmin = assignParam(
true,
Boolean(
req?.kauth?.grant?.access_token?.content?.resource_access?.[
'manager-admin'
]?.roles?.includes('manager_admin'),
),
)
req.userId = assignParam(
process.env['KC.DEV.ID'],
req.kauth?.grant?.access_token?.content?.sub,
)
req.user = assignParam(
{ sub: '123', name: 'dev' },
req.kauth?.grant?.access_token?.content,
)
next()
}
const adminOnly = [
parseToken,
(req, res, next) => {
if (!req.isAdmin) {
// user's role is not authorized
return res.status(403).send({ code: 4, error: 'Access denied' })
}
next()
},
]
module.exports = {
adminOnly,
parseToken,
}

View File

@@ -0,0 +1,18 @@
const { getAnswer } = require('../utils/common');
function errorHandler(err, req, res, _next) {
console.error(err);
if (typeof (err) === 'string') {
return res.status(400).json(getAnswer([{ message: err }]));
}
if (err.name === 'UnauthorizedError') {
// jwt authentication error
return res.status(401).json(getAnswer([{ message: 'Invalid Token' }]));
}
// default to 500 server error
return res.status(500).json(getAnswer([{ message: err?.message || 'Invalid Token' }]));
}
module.exports = errorHandler;

36
server/index.js Normal file
View File

@@ -0,0 +1,36 @@
const express = require("express");
const bodyParser = require("body-parser");
const cookieParser = require("cookie-parser");
const session = require("express-session");
const app = express();
require("dotenv").config();
require("./mailer");
const errorHandler = require("./_helpers/error-handler");
const { keycloak } = require("./kc");
app.use(
process.env.NODE_ENV !== "production"
? (_, __, next) => next()
: keycloak.middleware()
);
app.use(cookieParser());
app.use(
session({ secret: "so secret", resave: true, saveUninitialized: true })
);
app.use('/api', require('./routes'));
app.use(bodyParser.json({ limit: "50mb" }));
app.use(bodyParser.urlencoded({ limit: "50mb", extended: true }));
app.use(errorHandler);
app.listen(process.env.MANAGER_PORT, () =>
console.log(`Listening on http://localhost:${process.env.MANAGER_PORT}`)
);
module.exports = app;

39
server/kc.js Normal file
View File

@@ -0,0 +1,39 @@
const Keycloak = require("keycloak-connect");
const keycloak = new Keycloak(
{},
{
clientId: "microfrontend-admin",
bearerOnly: true,
serverUrl: "https://kc.bro-js.ru",
realm: "bro-js",
}
);
const kcAdminClientPromise = import("@keycloak/keycloak-admin-client")
.then(
async ({ default: KcAdminClient }) =>
new KcAdminClient({
baseUrl: "https://kc.bro-js.ru",
realmName: "bro-js",
})
)
.then(async (kcAdminClient) => {
const credentials = {
username: process.env['KC.TUZ.USERNAME'],
password: process.env['KC.TUZ.PASSWORD'],
grant_type: "password",
grantType: "password",
clientId: "microfrontend-admin",
}
await kcAdminClient.auth(credentials);
setInterval(() => kcAdminClient.auth(credentials), 3 * 24 * 60 *60 * 1000);
return kcAdminClient;
});
module.exports = {
keycloak,
kcAdminClientPromise,
}

16
server/mailer.js Normal file
View File

@@ -0,0 +1,16 @@
const { AdminNotificationRequest, addToQueue, configs, init } = require('@brojs/mailer');
const rc = require('./.serverrc');
const pkg = require('../package');
init({
userName: process.env.SMTP_MAIL_LOGIN,
password: process.env.SMTP_MAIL_PASSWORD,
adminMails: process.env.MAIL_TO_1,
smtpConfig: configs.yandex,
queTimer: rc.mailStepTimer,
});
if (process.env.MAIL_TO_1 && process.env.NODE_ENV === 'production') {
addToQueue(new AdminNotificationRequest(`Деплой kc админки v${pkg.version} прошёл успешно (${process.env.ADMIN_FRONT_BASE_NAME}) (Время ${new Date().toLocaleString()})`));
}

8
server/routes/index.js Normal file
View File

@@ -0,0 +1,8 @@
const router = require('express').Router();
const pkg = require('../../package.json')
router.get('/healthcheck', (req, res) => {
res.send({ ok: true, version: pkg.version })
})
module.exports = router;

22
server/utils/common.js Normal file
View File

@@ -0,0 +1,22 @@
const getAnswer = (error, body = null, success = true) => {
if (error) {
return { success: false, error, body }
} else {
return { success, body }
}
}
function cleanId(entity) {
if (Array.isArray(entity)) {
return entity.map(cleanId)
}
const { _id, ...other } = entity;
return { ...other, id: _id };
}
module.exports = {
getAnswer,
cleanId,
}