mirror of
https://gitea.smigz.com/smiggiddy/odin-codeprojects.git
synced 2025-06-28 04:45:36 -04:00
189 lines
4.9 KiB
JavaScript
189 lines
4.9 KiB
JavaScript
const path = require("node:path");
|
|
const { Pool } = require("pg");
|
|
const express = require("express");
|
|
const session = require("express-session");
|
|
const passport = require("passport");
|
|
const LocalStrategy = require("passport-local");
|
|
const GoogleStrategy = require("passport-google-oauth").OAuth2Strategy;
|
|
const fs = require("node:fs");
|
|
const bcryptjs = require("bcryptjs");
|
|
|
|
const pool = new Pool({
|
|
connectionString: process.env.CONNECTION_STRING,
|
|
});
|
|
|
|
const initSQL = path.join(__dirname, "../migrations/init.sql");
|
|
|
|
fs.readFile(initSQL, "utf8", (err, data) => {
|
|
if (err) {
|
|
console.error(err);
|
|
return;
|
|
}
|
|
pool.query(data);
|
|
});
|
|
|
|
console.log(process.env.DEEZNUTS);
|
|
const app = express();
|
|
app.set("views", path.join(__dirname, "views"));
|
|
app.set("view engine", "ejs");
|
|
|
|
//app.use(session({ secret: "cats", resave: false, saveUninitialized: false }));
|
|
app.use(
|
|
session({
|
|
store: new (require("connect-pg-simple")(session))({
|
|
pool: pool,
|
|
tableName: "user_sessions",
|
|
createTableIfMissing: true,
|
|
}),
|
|
resave: false,
|
|
cookie: { maxAge: 30 * 24 * 60 * 60 * 1000 },
|
|
saveUninitialized: false,
|
|
secret: "deezNuts",
|
|
}),
|
|
);
|
|
app.use(passport.session());
|
|
app.use(express.urlencoded({ extended: false }));
|
|
|
|
app.listen(3000, () => console.log("app running on port 3000"));
|
|
|
|
passport.use(
|
|
new LocalStrategy(async (username, password, done) => {
|
|
try {
|
|
const { rows } = await pool.query(
|
|
"SELECT * FROM users WHERE username = $1",
|
|
[username],
|
|
);
|
|
const user = rows[0];
|
|
const match = await bcryptjs.compare(password, user.password);
|
|
|
|
if (!user) {
|
|
return done(null, false, { message: "Incorrect username/password." });
|
|
}
|
|
|
|
if (!match) {
|
|
return done(null, false, { message: "incorrect username/password" });
|
|
}
|
|
|
|
return done(null, user);
|
|
} catch (err) {
|
|
return done(err);
|
|
}
|
|
}),
|
|
);
|
|
|
|
passport.use(
|
|
new GoogleStrategy(
|
|
{
|
|
clientID: process.env["GOOGLE_CLIENT_ID"],
|
|
clientSecret: process.env["GOOGLE_CLIENT_SECRET"],
|
|
callbackURL: "/oauth2/redirect/google",
|
|
scope: ["profile"],
|
|
},
|
|
async function verify(accessToken, refreshToken, profile, cb) {
|
|
try {
|
|
await pool.query("BEGIN");
|
|
const { rows: federatedRows } = await pool.query(
|
|
"SELECT * FROM federated_credentials WHERE provider = $1 AND subject = $2",
|
|
["https://accounts.google.com", profile.id],
|
|
);
|
|
let id = federatedRows.length > 0 ? federatedRows[0].user_id : null;
|
|
if (federatedRows.length === 0) {
|
|
const { rows: newUserRows } = await pool.query(
|
|
"INSERT INTO users (username) VALUES ($1) RETURNING *",
|
|
[profile.displayName],
|
|
);
|
|
id = newUserRows[0].id;
|
|
await pool.query(
|
|
"INSERT INTO federated_credentials (user_id, provider, subject) VALUES ($1, $2, $3)",
|
|
[id, "https://accounts.google.com", profile.id],
|
|
);
|
|
const user = {
|
|
id: id,
|
|
name: profile.displayName,
|
|
};
|
|
pool.query("COMMIT");
|
|
cb(null, user);
|
|
} else {
|
|
const { rows: userRows } = await pool.query(
|
|
"SELECT * FROM users WHERE id = $1",
|
|
[id],
|
|
);
|
|
cb(null, userRows[0]);
|
|
}
|
|
} catch (e) {
|
|
await pool.query("ROLLBACK");
|
|
cb(e);
|
|
}
|
|
},
|
|
),
|
|
);
|
|
|
|
passport.serializeUser((user, done) => {
|
|
done(null, user.id);
|
|
});
|
|
|
|
passport.deserializeUser(async (id, done) => {
|
|
try {
|
|
const { rows } = await pool.query("SELECT * FROM users WHERE id= $1", [id]);
|
|
const user = rows[0];
|
|
done(null, user);
|
|
} catch (e) {
|
|
done(e);
|
|
}
|
|
});
|
|
|
|
app.use((req, res, next) => {
|
|
console.log(req.user);
|
|
console.table(req.session.passport);
|
|
next();
|
|
});
|
|
|
|
app.get("/", (req, res) => {
|
|
if (req.session.viewCount) {
|
|
req.session.viewCount++;
|
|
} else {
|
|
req.session.viewCount = 1;
|
|
req.session.deezNuts = "big AF dog";
|
|
}
|
|
res.render("index", { user: req.user, sessions: req.session.viewCount });
|
|
});
|
|
|
|
app.get("/sign-up", (req, res) => res.render("sign-up-form"));
|
|
app.post("/sign-up", async (req, res, next) => {
|
|
try {
|
|
const hashedPassword = await bcryptjs.hash(req.body.password, 10);
|
|
await pool.query("INSERT INTO users (username, password) VALUES ($1, $2)", [
|
|
req.body.username,
|
|
hashedPassword,
|
|
]);
|
|
res.redirect("/");
|
|
} catch (err) {
|
|
next(err);
|
|
}
|
|
});
|
|
|
|
app.post(
|
|
"/log-in",
|
|
passport.authenticate("local", {
|
|
successRedirect: "/",
|
|
failureRedirect: "/",
|
|
}),
|
|
);
|
|
|
|
app.get("/log-out", (req, res, next) => {
|
|
req.logout((err) => {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
res.redirect("/");
|
|
});
|
|
});
|
|
|
|
app.get("/login/federated/google", passport.authenticate("google"));
|
|
app.get(
|
|
"/oauth2/redirect/google",
|
|
passport.authenticate("google", {
|
|
successRedirect: "/",
|
|
failureRedirect: "/login",
|
|
}),
|
|
);
|