use https

This commit is contained in:
Will Bradley 2025-07-16 19:01:15 -07:00
parent ea3bfc8b8f
commit e432d43376
2 changed files with 92 additions and 50 deletions

View File

@ -13,4 +13,5 @@ INSTAGRAM_CLIENT_SECRET=your-instagram-client-secret
DATABASE_URL=./water_stations.db
# Server configuration
PORT=3000
PORT=3000
FORCE_HTTPS=false

139
server.js
View File

@ -15,6 +15,7 @@ require('dotenv').config();
const app = express();
const HOST = process.env.HOST || "0.0.0.0";
const PORT = process.env.PORT || 3000;
const FORCE_HTTPS = process.env.FORCE_HTTPS === 'true';
// Database setup
const db = new sqlite3.Database('./water_stations.db');
@ -91,6 +92,17 @@ app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static(path.join(__dirname, 'public')));
// HTTPS enforcement middleware
if (FORCE_HTTPS) {
app.use((req, res, next) => {
if (req.header('x-forwarded-proto') !== 'https') {
res.redirect(`https://${req.header('host')}${req.url}`);
} else {
next();
}
});
}
app.use(session({
store: new SQLiteStore({
db: 'water_stations.db',
@ -100,7 +112,7 @@ app.use(session({
resave: false,
saveUninitialized: false,
cookie: {
secure: false, // Set to true in production with HTTPS
secure: FORCE_HTTPS, // Use secure cookies when HTTPS is forced
maxAge: 7 * 24 * 60 * 60 * 1000 // 7 days
}
}));
@ -108,6 +120,13 @@ app.use(session({
app.use(passport.initialize());
app.use(passport.session());
// Helper function to get base URL
function getBaseUrl(req) {
const protocol = FORCE_HTTPS || req.secure || req.header('x-forwarded-proto') === 'https' ? 'https' : 'http';
const host = req.header('host');
return `${protocol}://${host}`;
}
// Passport configuration
passport.use(new LocalStrategy(
{ usernameField: 'username' },
@ -124,55 +143,67 @@ passport.use(new LocalStrategy(
}
));
passport.use(new GoogleStrategy({
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: "/auth/google/callback"
}, (accessToken, refreshToken, profile, done) => {
db.get('SELECT * FROM users WHERE google_id = ?', [profile.id], (err, user) => {
if (err) return done(err);
if (user) {
return done(null, user);
} else {
db.run('INSERT INTO users (google_id, display_name, email) VALUES (?, ?, ?)',
[profile.id, profile.displayName, profile.emails[0].value],
function(err) {
if (err) return done(err);
db.get('SELECT * FROM users WHERE id = ?', [this.lastID], (err, user) => {
return done(err, user);
});
}
);
}
});
}));
// Initialize OAuth strategies with dynamic callback URLs
function initializeOAuthStrategies(baseUrl = '') {
// Clear existing strategies
passport.unuse('google');
passport.unuse('instagram');
// Google OAuth Strategy
passport.use(new GoogleStrategy({
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: `${baseUrl}/auth/google/callback`
}, (accessToken, refreshToken, profile, done) => {
db.get('SELECT * FROM users WHERE google_id = ?', [profile.id], (err, user) => {
if (err) return done(err);
if (user) {
return done(null, user);
} else {
db.run('INSERT INTO users (google_id, display_name, email) VALUES (?, ?, ?)',
[profile.id, profile.displayName, profile.emails[0].value],
function(err) {
if (err) return done(err);
db.get('SELECT * FROM users WHERE id = ?', [this.lastID], (err, user) => {
return done(err, user);
});
}
);
}
});
}));
passport.use(new InstagramStrategy({
clientID: process.env.INSTAGRAM_CLIENT_ID,
clientSecret: process.env.INSTAGRAM_CLIENT_SECRET,
callbackURL: "/auth/instagram/callback"
}, (accessToken, refreshToken, profile, done) => {
db.get('SELECT * FROM users WHERE instagram_id = ?', [profile.id], (err, user) => {
if (err) return done(err);
if (user) {
return done(null, user);
} else {
db.run('INSERT INTO users (instagram_id, display_name) VALUES (?, ?)',
[profile.id, profile.displayName],
function(err) {
if (err) return done(err);
db.get('SELECT * FROM users WHERE id = ?', [this.lastID], (err, user) => {
return done(err, user);
});
}
);
}
});
}));
// Instagram OAuth Strategy
passport.use(new InstagramStrategy({
clientID: process.env.INSTAGRAM_CLIENT_ID,
clientSecret: process.env.INSTAGRAM_CLIENT_SECRET,
callbackURL: `${baseUrl}/auth/instagram/callback`
}, (accessToken, refreshToken, profile, done) => {
db.get('SELECT * FROM users WHERE instagram_id = ?', [profile.id], (err, user) => {
if (err) return done(err);
if (user) {
return done(null, user);
} else {
db.run('INSERT INTO users (instagram_id, display_name) VALUES (?, ?)',
[profile.id, profile.displayName],
function(err) {
if (err) return done(err);
db.get('SELECT * FROM users WHERE id = ?', [this.lastID], (err, user) => {
return done(err, user);
});
}
);
}
});
}));
}
// Initialize OAuth strategies with empty base URL (will be updated per request)
initializeOAuthStrategies();
passport.serializeUser((user, done) => {
done(null, user.id);
@ -198,6 +229,11 @@ app.get('/auth/google', (req, res, next) => {
if (req.query.redirect) {
req.session.redirectUrl = req.query.redirect;
}
// Reinitialize strategies with current request's base URL
const baseUrl = getBaseUrl(req);
initializeOAuthStrategies(baseUrl);
passport.authenticate('google', { scope: ['profile', 'email'] })(req, res, next);
});
@ -214,6 +250,11 @@ app.get('/auth/instagram', (req, res, next) => {
if (req.query.redirect) {
req.session.redirectUrl = req.query.redirect;
}
// Reinitialize strategies with current request's base URL
const baseUrl = getBaseUrl(req);
initializeOAuthStrategies(baseUrl);
passport.authenticate('instagram')(req, res, next);
});