Skip to content
Snippets Groups Projects
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
No related branches found
No related tags found
1 merge request!4Dev
......@@ -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} ...`)
);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment