-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.js
159 lines (135 loc) · 5.15 KB
/
server.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
require('dotenv').config(); // Load environment variables
const express = require('express');
const cors = require('cors');
const crypto = require('crypto'); // Import the crypto module
const { client, connectDB } = require('./db/connection'); // Import the client and connectDB
const https = require('https');
const fs = require('fs');
const passport = require('passport');
const SamlStrategy = require('@node-saml/passport-saml').Strategy;
const session = require('express-session');
const bodyParser = require("body-parser");
const morgan = require('morgan');
const app = express();
// List of allowed origins
const allowedOrigins = [
'https://facelect.capping.ecrl.marist.edu',
'https://api-a1cc77df.duosecurity.com',
'https://auth.it.marist.edu',
];
app.use(cors());
app.use(express.json()); // Parse incoming JSON data
app.use(morgan('common')); // Log HTTP requests
// Configure session middleware
app.use(session({
secret: 'your-secret-key',
resave: false,
saveUninitialized: true,
// cookie: { secure: process.env.NODE_ENV === 'production' } // Ensure cookies are only used over HTTPS in production
}));
// Initialize Passport and restore authentication state, if any, from the session
app.use(passport.initialize());
app.use(passport.session());
// Connect to the PostgreSQL database
connectDB();
// Function to hash passwords using SHA-256
const hashPassword = (password) => {
return crypto.createHash('sha256').update(password).digest('hex');
};
// Passport SAML strategy configuration
passport.use(new SamlStrategy(
{
callbackUrl: 'https://facelect.capping.ecrl.marist.edu/login/callback',
entryPoint: 'https://auth.it.marist.edu/idp/profile/SAML2/Redirect/SSO',
issuer: 'https://facelect.capping.ecrl.marist.edu',
decryptionPvk: fs.readFileSync('./backend/facelect.capping.ecrl.marist.edu.pem', 'utf-8'),
privateCert: fs.readFileSync('./backend/2024_facelect.capping.ecrl.marist.edu.pem', 'utf-8'),
idpCert: fs.readFileSync('./backend/idp_cert.pem', 'utf-8'),
},
(profile, done) => {
// Extract user information from the profile
const user = {
email: profile.emailAddress,
};
return done(null, user);
}
));
passport.serializeUser((user, done) => {
done(null, user);
});
passport.deserializeUser((user, done) => {
done(null, user);
});
// SSO callback route
app.post(
'https://facelect.capping.ecrl.marist.edu/login/callback',
bodyParser.urlencoded({ extended: false }),
passport.authenticate("saml", {
failureRedirect: "/",
failureFlash: true,
}),
function (req, res) {
res.redirect("/user-profile");
},
);
// SSO login route
app.get('/sso/login',
passport.authenticate("saml", { failureRedirect: "/", failureFlash: true }),
function (req, res) {
res.redirect("/");
},
);
// Route to handle admin login
app.post('/admin-login', async (req, res) => {
const { username, password } = req.body; // Capture username and password from request
try {
// Query the Admins table to find the admin by username (Uname)
const adminResult = await client.query('SELECT * FROM Admins WHERE Uname = $1', [username]);
if (adminResult.rows.length === 0) {
return res.status(400).json({ message: 'Invalid username or password' });
}
const admin = adminResult.rows[0];
// Hash the provided password and compare with the stored hash
const hashedInputPassword = hashPassword(password); // Hash the input password
if (hashedInputPassword !== admin.thepassword) { // Use correct case for ThePassword
return res.status(400).json({ message: 'Invalid username or password' });
}
// If successful, return a success message (can also return user data if needed)
res.json({ message: 'Login successful', admin: { AID: admin.AID, Uname: admin.Uname, Godmode: admin.Godmode } });
} catch (err) {
console.error('Error during login:', err);
res.status(500).json({ message: 'Server error' });
}
});
// Example existing route for fetching faculty data (unchanged)
app.get('/faculty', async (req, res) => {
try {
const result = await client.query(`
SELECT
faculty.fid,
faculty.email,
faculty.ishidden,
faculty.prefname,
faculty.url,
faculty.thestatement,
faculty.lastupdated,
schools.sname AS sname
FROM faculty
LEFT JOIN schools ON faculty.schoolid = schools.sid;
`);
res.json(result.rows);
} catch (err) {
console.error('Database query error:', err);
res.status(500).send('Error querying the database');
}
});
// Read SSL certificate and key
const options = {
key: fs.readFileSync('./backend/facelect.capping.ecrl.marist.edu.pem'),
cert: fs.readFileSync('./backend/2024_facelect.capping.ecrl.marist.edu.pem'),
ca: fs.readFileSync('./backend/2024_InCommonCA.crt'),
};
// Create HTTPS server on port 3001
https.createServer(options, app).listen(3001, () => {
console.log('HTTPS Server running on port 3001');
});