qinglong/back/loaders/express.ts
2021-06-06 16:49:23 +08:00

107 lines
2.4 KiB
TypeScript

import { Request, Response, NextFunction, Application } from 'express';
import bodyParser from 'body-parser';
import cors from 'cors';
import routes from '../api';
import config from '../config';
import jwt from 'express-jwt';
import fs from 'fs';
import http from 'http';
import expressWs from 'express-ws';
const excludePath = ['/api/login'];
const auth = (getToken?: jwt.Options['getToken']) =>
jwt({
secret: config.secret as string,
algorithms: ['HS384'],
getToken,
});
const getTokenFromReq = (req) => {
if (
req.headers.authorization &&
req.headers.authorization.split(' ')[0] === 'Bearer'
) {
return req.headers.authorization.split(' ')[1];
} else if (req.query && req.query.token) {
return req.query.token;
}
return null;
};
export default ({ app }: { app: Application }) => {
const server = http.createServer(app);
app.listen = function serverListen(...args) {
return server.listen(...args);
};
expressWs(app, server);
app.enable('trust proxy');
app.use(cors());
app.use(bodyParser.json({ limit: '50mb' }));
app.use(bodyParser.urlencoded({ limit: '50mb', extended: true }));
app.use(
auth(getTokenFromReq).unless({
path: excludePath,
}),
);
app.use((req, res, next) => {
if (req.url && excludePath.includes(req.path)) {
return next();
}
const data = fs.readFileSync(config.authConfigFile, 'utf8');
const authHeader = getTokenFromReq(req);
if (data) {
const { token } = JSON.parse(data);
if (token && authHeader.includes(token)) {
return next();
}
}
const err: any = new Error('UnauthorizedError');
err['status'] = 401;
next(err);
});
app.use(config.api.prefix, routes());
app.use((req, res, next) => {
const err: any = new Error('Not Found');
err['status'] = 404;
next(err);
});
app.use(
(
err: Error & { status: number },
req: Request,
res: Response,
next: NextFunction,
) => {
if (err.name === 'UnauthorizedError') {
return res
.status(err.status)
.send({ code: 401, message: err.message })
.end();
}
return next(err);
},
);
app.use(
(
err: Error & { status: number },
req: Request,
res: Response,
next: NextFunction,
) => {
res.status(err.status || 500);
res.json({
code: err.status || 500,
message: err.message,
});
},
);
};