Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Simen Vevik
ntnu-beta-web
Commits
66432d50
Commit
66432d50
authored
Jan 07, 2020
by
Simen Vevik
Browse files
Merge branch 'dev' into 'master'
Dev See merge request
!4
parents
90345db1
f265f017
Changes
14
Hide whitespace changes
Inline
Side-by-side
.gitignore
View file @
66432d50
...
...
@@ -4,6 +4,7 @@ node_modules
.DS_Store
config/
data/
# default.json
# *.cert
# *.crt
...
...
client/Dockerfile
View file @
66432d50
### 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
client/src/App.js
View file @
66432d50
...
...
@@ -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
();
}
};
...
...
client/src/authentication.js
View file @
66432d50
...
...
@@ -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
"
);
...
...
client/src/utils/api.js
View file @
66432d50
const
setEndpoint
=
()
=>
{
const
PORT
=
process
.
env
.
PORT
||
5000
;
if
(
!
process
.
env
.
NODE_ENV
||
process
.
env
.
NODE_ENV
===
"
development
"
)
{
return
`http
s
://localhost:
${
PORT
}
/`
;
return
`http://localhost:
${
PORT
}
/`
;
}
else
{
return
`https://beta-katalog.it.ntnu.no:
${
PORT
}
/`
;
}
...
...
docker-compose.yml
View file @
66432d50
...
...
@@ -41,6 +41,7 @@ services:
restart
:
always
ports
:
-
"
443:443"
-
"
80:80"
volumes
:
-
./client:/client
-
/client/node_modules
...
...
server/middleware/auth.js
View file @
66432d50
...
...
@@ -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
"
);
...
...
server/middleware/db.js
View file @
66432d50
...
...
@@ -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();
...
...
server/middleware/passport.js
View file @
66432d50
...
...
@@ -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
)
{
...
...
server/package.json
View file @
66432d50
...
...
@@ -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"
,
...
...
server/routes/api/auth.js
View file @
66432d50
...
...
@@ -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
:
tru
e
}),
express
.
urlencoded
({
extended
:
fals
e
}),
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_redir
ect
"
)
);
res
.
redirect
(
SLO_redir
);
});
// @route GET /api/auth/logged_out
...
...
server/routes/api/logged-in.js
View file @
66432d50
...
...
@@ -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
);
});
...
...
server/routes/api/login.js
View file @
66432d50
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
;
server/server.js
View file @
66432d50
...
...
@@ -32,8 +32,9 @@ const certificate = fs.readFileSync(
const
credentials
=
{
key
:
privateKey
,
cert
:
certificate
,
passphrase
:
"
s
ecret
"
,
passphrase
:
config
.
get
(
"
app.sslS
ecret
"
)
,
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
}
...`
)
);
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment