Commit 66432d50 authored by Simen Vevik's avatar Simen Vevik
Browse files

Merge branch 'dev' into 'master'

Dev

See merge request !4
parents 90345db1 f265f017
......@@ -4,6 +4,7 @@ node_modules
.DS_Store
config/
data/
# default.json
# *.cert
# *.crt
......
### Stage 1: Build ###
### Stage 1: React Production Build ###
# Use standard version of Node as a parent image
FROM node:10 as build
......@@ -15,12 +15,15 @@ COPY . /usr/src/app/
# Create the production build
RUN npm run-script build
### Stage 2: Production env ###
### Stage 2: Apache Config ###
### 2.1 Apache setup
# Use apache image as webserver
FROM httpd:2.4
# Copy the production build into apache folders
COPY --from=build /usr/src/app/build /usr/local/apache2/htdocs/
### 2.2 SSL config
# Copy SSL certificate into apache conf
COPY --from=build /usr/src/app/config/ssl/* /usr/local/apache2/conf/
# Enable SSL
......@@ -29,9 +32,23 @@ RUN sed -i \
-e 's/^#\(LoadModule .*mod_ssl.so\)/\1/' \
-e 's/^#\(LoadModule .*mod_socache_shmcb.so\)/\1/' \
/usr/local/apache2/conf/httpd.conf
### 2.3 Server side routing /* to index.html with .htaccess rules
# Copy .htaccess to root folder
COPY --from=build /usr/src/app/config/.htaccess /usr/local/apache2/htdocs
# Enable .htaccess
RUN sed -i \
'/<Directory "\/usr\/local\/apache2\/htdocs">/,/<\/Directory>/ s/AllowOverride None/AllowOverride all/' \
/usr/local/apache2/conf/httpd.conf
# Enable mod_rewrite
RUN echo "LoadModule rewrite_module modules/mod_rewrite.so" >> /usr/local/apache2/conf/httpd.conf
### 2.4
# Set ServerName
RUN echo "ServerName beta-katalog.it.ntnu.no" >> /usr/local/apache2/conf/httpd.conf
# Open the container port
EXPOSE 443
### 2.5 Open ports and start apache
# Open the container ports
EXPOSE 443 80
# Start apache webserver
CMD ["apachectl", "-D", "FOREGROUND"]
\ No newline at end of file
......@@ -14,7 +14,7 @@ import { ENDPOINT } from "./utils/api";
// The express server uses a self signed certificate for HTTPS
// The line below ignores the fact that the certificate is not trusted
// when doing API calls
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;
// process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;
class App extends React.Component {
constructor(props) {
......@@ -28,7 +28,7 @@ class App extends React.Component {
componentDidMount() {
this.setUser();
this.checkFeide();
// this.checkFeide();
}
clearSession = () => {
......@@ -48,6 +48,8 @@ class App extends React.Component {
if (this.state.user !== email) {
this.setState({ user: email });
}
} else {
this.checkFeide();
}
};
......
......@@ -3,6 +3,8 @@ import React from "react";
import { Redirect } from "react-router-dom";
import { ENDPOINT } from "./utils/api";
axios.defaults.withCredentials = true;
const login = async (email, password) => {
localStorage.removeItem("currentUser");
......
const setEndpoint = () => {
const PORT = process.env.PORT || 5000;
if (!process.env.NODE_ENV || process.env.NODE_ENV === "development") {
return `https://localhost:${PORT}/`;
return `http://localhost:${PORT}/`;
} else {
return `https://beta-katalog.it.ntnu.no:${PORT}/`;
}
......
......@@ -41,6 +41,7 @@ services:
restart: always
ports:
- "443:443"
- "80:80"
volumes:
- ./client:/client
- /client/node_modules
......
......@@ -4,15 +4,15 @@ const jwt = require("jsonwebtoken");
const config = require("config");
module.exports = function(req, res, next) {
console.log(req.isAuthenticated());
// console.log(req.isAuthenticated());
// Check if user is logged into Feide
if (req.isAuthenticated()) {
console.log(req.session.passport.user);
// console.log(req.session.passport.user);
next();
// Check if user is logged in
} else {
console.log("Not feide user");
// console.log("Not feide user");
// Get token from header
const token = req.header("x-auth-token");
......
......@@ -3,11 +3,28 @@
const mysql = require("mysql");
const config = require("config");
const host =
process.env.NODE_ENV === "development"
? config.get("db-remote.host")
: config.get("db.host");
const user =
process.env.NODE_ENV === "development"
? config.get("db-remote.user")
: config.get("db.user");
const password =
process.env.NODE_ENV === "development"
? config.get("db-remote.password")
: config.get("db.password");
const database =
process.env.NODE_ENV === "development"
? config.get("db-remote.database")
: config.get("db.database");
const connection = mysql.createConnection({
host: config.get("db.host"),
user: config.get("db.user"),
password: config.get("db.password"),
database: config.get("db.database")
host: host,
user: user,
password: password,
database: database
});
// connection.connect();
......
......@@ -10,12 +10,17 @@ module.exports = function(passport) {
done(null, user);
});
const issuer =
process.env.NODE_env === "development"
? "http://localhost:5000/api/auth/login/callback"
: config.get("passport.issuer");
passport.use(
new SamlStrategy(
{
path: config.get("passport.path"),
entryPoint: config.get("passport.entryPoint"),
issuer: config.get("passport.issuer")
issuer: issuer
// cert: config.get("passport.cert")
},
function(profile, done) {
......
......@@ -6,7 +6,7 @@
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node server.js",
"server": "nodemon server.js"
"server": "set NODE_ENV=development&&nodemon server.js"
},
"author": "",
"license": "ISC",
......
......@@ -6,6 +6,15 @@ const auth = require("../../middleware/auth");
const path = require("path");
const config = require("config");
const SLO_redir =
process.env.NODE_ENV === "development"
? "http://localhost:3000/login"
: config.get("passport.SLO_redirect");
const SSO_redir =
process.env.NODE_ENV === "development"
? "http://localhost:3000/"
: config.get("passport.SSO_redirect");
/*
-----
Routes used by Feide IDP
......@@ -17,17 +26,18 @@ Routes used by Feide IDP
// @access Public
router.post(
"/login/callback",
bodyParser.urlencoded({ extended: true }),
express.urlencoded({ extended: false }),
passport.authenticate("saml", {
failureRedirect: config.get("passport.SLO_redirect")
failureRedirect: SLO_redir
// session: true
// failureRedirect: config.get("passport.SLO_redirect")
// failureFlash: true
}),
function(req, res) {
console.log(req.isAuthenticated());
console.log("SAML auth sucess");
req.session.save(() => {
res.redirect(config.get("passport.SSO_redirect"));
});
// req.session.save(() => {
// res.redirect(SSO_redir);
// });
res.redirect(SSO_redir);
}
);
......@@ -51,7 +61,7 @@ router.get(
// @access Public
router.get("/logout", function(req, res) {
req.logout();
res.redirect(config.get("passport.SLO_redirect"));
res.redirect(SLO_redir);
});
// @route GET /api/auth/logged_out
......
......@@ -14,6 +14,7 @@ router.get("/admin", [auth, admin], (req, res) => {
// @desc Verify user is logged in (check token)
// @access Private
router.get("/", auth, (req, res) => {
console.log(req.user);
res.send(req.user);
});
......
const express = require('express');
const express = require("express");
const router = express.Router();
const auth = require('../../middleware/auth');
const User = require('../../models/Users');
const jwt = require('jsonwebtoken');
const config = require('config');
const { check, validationResult } = require('express-validator');
const bcrypt = require('bcryptjs');
const auth = require("../../middleware/auth");
const User = require("../../models/Users");
const jwt = require("jsonwebtoken");
const config = require("config");
const { check, validationResult } = require("express-validator");
const bcrypt = require("bcryptjs");
// @route POST api/login
// @desc Auth user and get token
// @access Public
router.post(
'/',
[
check('email', 'Include a valid email').isEmail(),
check('password', 'Password is required').exists()
],
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const { email, password } = req.body;
try {
await User.getOne(email, function(err, user) {
// See if user exists
if(!user) {
return res.status(400).json({ msg: 'Invalid credentials' });
}
if(user[0].access === 0) {
return res.status(401).json({ msg: 'Need approval from admin' })
}
"/",
[
check("email", "Include a valid email").isEmail(),
check("password", "Password is required").exists()
],
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const { email, password } = req.body;
// Validate email & password
async function checkUser(user, password) {
const match = await bcrypt.compare(password, user.password);
if (!match) {
return res.status(400).json({ msg: 'Invalid credentials' });
}
const admin = user.admin === 1 ? true : false;
try {
await User.getOne(email, function(err, user) {
// See if user exists
if (!user) {
return res.status(400).json({ msg: "Invalid credentials" });
}
if (user[0].access === 0) {
return res.status(401).json({ msg: "Need approval from admin" });
}
const payload = {
user: {
id: user.email
}
}
jwt.sign(
payload,
config.get('jwtSecret'),
{ expiresIn: 14400 }, // 3600 seconds = 1 hour
(err, token) => {
if(err) throw err;
console.log('admin');
console.log(admin);
res.json({ token: token, admin: admin })
}
);
// Validate email & password
async function checkUser(user, password) {
const match = await bcrypt.compare(password, user.password);
if (!match) {
return res.status(400).json({ msg: "Invalid credentials" });
}
}
checkUser(user[0], password);
})
const admin = user.admin === 1 ? true : false;
const payload = {
user: {
id: user.email
}
};
} catch(err) {
console.error(err);
res.status(500).send('Server error');
jwt.sign(
payload,
config.get("jwtSecret"),
{ expiresIn: 14400 }, // 14400 seconds = 4 hours
(err, token) => {
if (err) throw err;
console.log("admin");
console.log(admin);
res.json({ token: token, admin: admin });
}
);
}
checkUser(user[0], password);
});
} catch (err) {
console.error(err);
res.status(500).send("Server error");
}
}
);
module.exports = router;
\ No newline at end of file
module.exports = router;
......@@ -32,8 +32,9 @@ const certificate = fs.readFileSync(
const credentials = {
key: privateKey,
cert: certificate,
passphrase: "secret",
passphrase: config.get("app.sslSecret"),
requestCert: false,
// rejectUnauthorized should be true (server certificate will be verified against lists of CAs)
rejectUnauthorized: false
};
......@@ -42,19 +43,37 @@ require("./middleware/passport")(passport);
// Init Middleware
// Express comes with npm body-parser, which is used to parse http post requests
// Parse incomming requests with req.body
app.use(express.json({ extended: false }));
// app.use(express.json({ extended: false }));
// app.use(cookieParser(config.get("app.session")));
app.use(cookieParser());
app.use(express.json());
app.use(function(req, res, next) {
// Match the domain you will make the request from
res.header("Access-Control-Allow-Origin", "*");
// res.header("Access-Control-Allow-Origin", "*");
// res.header("Access-Control-Allow-Origin", [
// "http://localhost:3000",
// "https://beta-katalog.it.ntnu.no",
// "https://beta.it.ntnu.no"
// ]);
// Will this work without reverse proxy?
const corsWhitelist = [
"http://localhost:3000",
"https://beta-katalog.it.ntnu.no",
"https://beta.it.ntnu.no"
];
if (corsWhitelist.indexOf(req.headers.origin) !== -1) {
res.header("Access-Control-Allow-Origin", req.headers.origin);
}
res.header(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, x-auth-token, Content-Type, Accept"
);
res.header("Access-Control-Allow-Credentials", true);
res.header("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE");
next();
});
......@@ -98,8 +117,12 @@ if (process.env.NODE_ENV === "production") {
}
// Init server
https
.createServer(credentials, app)
.listen(PORT, () => console.log(`App running on PORT ${PORT} ...`));
// app.listen(PORT, () => console.log(`Server started on port ${PORT}`));
if (process.env.NODE_ENV === "development") {
app.listen(PORT, () => console.log(`HTTP server running on port ${PORT}`));
} else {
https
.createServer(credentials, app)
.listen(PORT, () =>
console.log(`HTTPS server running on PORT ${PORT} ...`)
);
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment