chat-with-gpt/server/src/passport.ts

88 lines
2.7 KiB
TypeScript
Raw Normal View History

2023-03-17 18:57:32 +00:00
import bcrypt from 'bcrypt';
2023-03-14 11:00:40 +00:00
import crypto from 'crypto';
import passport from 'passport';
import session from 'express-session';
import createSQLiteSessionStore from 'connect-sqlite3';
import { Strategy as LocalStrategy } from 'passport-local';
import ChatServer from './index';
2023-03-17 18:27:13 +00:00
const secret = process.env.AUTH_SECRET || crypto.randomBytes(32).toString('hex');
2023-03-14 11:00:40 +00:00
export function configurePassport(context: ChatServer) {
const SQLiteStore = createSQLiteSessionStore(session);
const sessionStore = new SQLiteStore({ db: 'sessions.db' });
passport.use(new LocalStrategy(async (email: string, password: string, cb: any) => {
const user = await context.database.getUser(email);
if (!user) {
return cb(null, false, { message: 'Incorrect username or password.' });
}
2023-03-17 18:57:32 +00:00
try {
console.log(user.salt ? 'Using pbkdf2' : 'Using bcrypt');
const isPasswordCorrect = user.salt
? crypto.timingSafeEqual(user.passwordHash, crypto.pbkdf2Sync(password, user.salt, 310000, 32, 'sha256'))
: await bcrypt.compare(password, user.passwordHash.toString());
2023-03-14 11:00:40 +00:00
2023-03-17 18:57:32 +00:00
if (!isPasswordCorrect) {
2023-03-14 11:00:40 +00:00
return cb(null, false, { message: 'Incorrect username or password.' });
}
return cb(null, user);
2023-03-17 18:57:32 +00:00
} catch (e) {
cb(e);
}
2023-03-14 11:00:40 +00:00
}));
passport.serializeUser((user: any, cb: any) => {
process.nextTick(() => {
cb(null, { id: user.id, username: user.username });
});
});
passport.deserializeUser((user: any, cb: any) => {
process.nextTick(() => {
return cb(null, user);
});
});
context.app.use(session({
2023-03-17 18:27:13 +00:00
secret,
2023-03-14 11:00:40 +00:00
resave: false,
saveUninitialized: false,
store: sessionStore as any,
}));
context.app.use(passport.authenticate('session'));
context.app.post('/chatapi/login', passport.authenticate('local', {
successRedirect: '/',
failureRedirect: '/?error=login'
}));
context.app.post('/chatapi/register', async (req, res, next) => {
const { username, password } = req.body;
2023-03-17 18:57:32 +00:00
const hashedPassword = await bcrypt.hash(password, 12);
try {
await context.database.createUser(username, Buffer.from(hashedPassword));
passport.authenticate('local')(req, res, () => {
res.redirect('/');
});
} catch (err) {
console.error(err);
res.redirect('/?error=register');
}
2023-03-14 11:00:40 +00:00
});
context.app.all('/chatapi/logout', (req, res, next) => {
req.logout((err) => {
if (err) {
return next(err);
}
res.redirect('/');
});
});
}