enhancement(lint): Fix lint errors for hackclub-spotify-bot/src/index.js

Co-authored-by: NeonGamerBot-QK <saahilattud@gmail.com>
Signed-off-by: zeon-neon[bot] <136533918+zeon-neon[bot]@users.noreply.github.com>
This commit is contained in:
zeon-neon[bot] 2024-10-12 22:01:21 +00:00 committed by GitHub
parent 2769295762
commit 7499857a57
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -2,9 +2,16 @@ const path = require("path");
require("dotenv").config(); require("dotenv").config();
const express = require("express"); const express = require("express");
const session = require("express-session"); const session = require("express-session");
const FileStore = require('session-file-store')(session); const FileStore = require("session-file-store")(session);
const { InstallProvider, FileInstallationStore } = require("@slack/oauth"); const { InstallProvider, FileInstallationStore } = require("@slack/oauth");
const { getLoginUrl, refreshToken, getCredentials, saveCredentials, spotifyRoutes, addSongToPlaylist } = require("./spotify"); const {
getLoginUrl,
refreshToken,
getCredentials,
saveCredentials,
spotifyRoutes,
addSongToPlaylist,
} = require("./spotify");
const { QuickDB } = require("quick.db"); const { QuickDB } = require("quick.db");
const db = new QuickDB({ const db = new QuickDB({
@ -12,22 +19,27 @@ const db = new QuickDB({
}); });
let cacheDb = {}; let cacheDb = {};
const app = express(); const app = express();
const userScopes = ['identity.avatar', 'identity.basic', 'identity.team'] const userScopes = ["identity.avatar", "identity.basic", "identity.team"];
// Initialize // Initialize
const oauth = new InstallProvider({ const oauth = new InstallProvider({
clientId: process.env.SLACK_CLIENT_ID, clientId: process.env.SLACK_CLIENT_ID,
clientSecret: process.env.SLACK_CLIENT_SECRET, clientSecret: process.env.SLACK_CLIENT_SECRET,
stateSecret: process.env.STATE_SECRET, stateSecret: process.env.STATE_SECRET,
stateVerification: false, stateVerification: false,
stateStore: new FileInstallationStore(path.join(__dirname, '../data/states.json')), stateStore: new FileInstallationStore(
installationStore: new FileInstallationStore(path.join(__dirname, '../data/installations.json')), path.join(__dirname, "../data/states.json"),
// installationStore: { ),
installationStore: new FileInstallationStore(
path.join(__dirname, "../data/installations.json"),
),
// installationStore: {
//} //}
stateStore: { stateStore: {
generateStateParam: (installUrlOptions, date) => { generateStateParam: (installUrlOptions, date) => {
// generate a random string to use as state in the URL // generate a random string to use as state in the URL
const randomState = process.env.STATE_SECRET + Math.random().toString(36).substring(7); const randomState =
process.env.STATE_SECRET + Math.random().toString(36).substring(7);
// save installOptions to cache/db // save installOptions to cache/db
cacheDb[randomState] = installUrlOptions; cacheDb[randomState] = installUrlOptions;
// myDB.set(randomState, installUrlOptions); // myDB.set(randomState, installUrlOptions);
@ -36,13 +48,13 @@ const oauth = new InstallProvider({
}, },
// verifyStateParam's first argument is a date object and the second argument is a string representing the state // verifyStateParam's first argument is a date object and the second argument is a string representing the state
// verifyStateParam is expected to return an object representing installUrlOptions // verifyStateParam is expected to return an object representing installUrlOptions
verifyStateParam: (date, state) => { verifyStateParam: (date, state) => {
return cacheDb[state]; return cacheDb[state];
// fetch saved installOptions from DB using state reference // fetch saved installOptions from DB using state reference
const installUrlOptions = myDB.get(randomState); const installUrlOptions = myDB.get(randomState);
return installUrlOptions; return installUrlOptions;
}, },
} },
}); });
app.use(express.json()); app.use(express.json());
app.use(express.static(path.join(__dirname, "public"))); app.use(express.static(path.join(__dirname, "public")));
@ -54,31 +66,32 @@ app.use(
secret: process.env.STATE_SECRET, secret: process.env.STATE_SECRET,
resave: true, resave: true,
store: new FileStore({ store: new FileStore({
path: path.join(__dirname, '../data/sessions'), path: path.join(__dirname, "../data/sessions"),
}), }),
saveUninitialized: true, saveUninitialized: true,
cookie: { secure: "auto", maxAge: 1000 * 60 * 60 * 24 * 365 }, cookie: { secure: "auto", maxAge: 1000 * 60 * 60 * 24 * 365 },
}), }),
); );
try { try {
const statusMonitor = require('express-status-monitor')({ const statusMonitor = require("express-status-monitor")({
healthChecks: [{ healthChecks: [
protocol: 'http', {
host: 'localhost', protocol: "http",
port: 3000, host: "localhost",
path: '/', port: 3000,
timeout: 1000, path: "/",
interval: 1000, timeout: 1000,
}] interval: 1000,
},
],
}); });
app.use(statusMonitor); app.use(statusMonitor);
app.use((req,res,next) => { app.use((req, res, next) => {
// console.debug([req.headers, req.session]) // console.debug([req.headers, req.session])
next() next();
}) });
} catch (e) { } catch (e) {
// we can ignore since this is an optional dependency // we can ignore since this is an optional dependency
} }
@ -86,37 +99,40 @@ app.get("/login", async (req, res) => {
if (req.session.token) { if (req.session.token) {
res.redirect("/home"); res.redirect("/home");
} else { } else {
res.redirect(await oauth.generateInstallUrl({ res.redirect(
// Add the scopes your app needs await oauth.generateInstallUrl({
redirectUri: process.env.SLACK_REDIRECT_URI, // Add the scopes your app needs
scopes: [], redirectUri: process.env.SLACK_REDIRECT_URI,
scopes: [],
userScopes: userScopes userScopes: userScopes,
})) }),
);
} }
}); });
app.get('/slack/callback', (req, res) => { app.get("/slack/callback", (req, res) => {
// console.debug(req.headers, req.url) // console.debug(req.headers, req.url)
oauth.handleCallback(req, res, { oauth.handleCallback(req, res, {
success: async (install) => { success: async (install) => {
// typings // typings
// user: { token:string , scopes: string[], id: string} // user: { token:string , scopes: string[], id: string}
// console.log(install) // console.log(install)
req.session.info = install req.session.info = install;
req.session.token = install.user.token req.session.token = install.user.token;
res.redirect('/home') res.redirect("/home");
}, },
failure: (err) => { failure: (err) => {
console.log(err); console.log(err);
res.send("Failed to install!, please contact neon in the slack!, \n" + err.stack); res.send(
"Failed to install!, please contact neon in the slack!, \n" + err.stack,
);
}, },
}); });
}); });
app.get('/logout', (req,res) => { app.get("/logout", (req, res) => {
req.session.destroy(); req.session.destroy();
res.redirect('/'); res.redirect("/");
}) });
app.get("/", (req, res) => { app.get("/", (req, res) => {
res.render("index", { res.render("index", {
title: "Hack Club Spotify Bot", title: "Hack Club Spotify Bot",
@ -127,9 +143,9 @@ const errorStrings = [
"Invalid CSRF Token!", // token = csrf token "Invalid CSRF Token!", // token = csrf token
"Song is not a track! (or not even a spotify song url)", "Song is not a track! (or not even a spotify song url)",
"Song already exists in the database! (its in the playlist or banned from the playlist)", "Song already exists in the database! (its in the playlist or banned from the playlist)",
] ];
app.get('/home', async (req,res) => { app.get("/home", async (req, res) => {
if(!req.session.info) return res.redirect('/login'); if (!req.session.info) return res.redirect("/login");
let onetimetoken = Math.random().toString(36).substring(7); let onetimetoken = Math.random().toString(36).substring(7);
cacheDb[onetimetoken] = true; cacheDb[onetimetoken] = true;
res.render("home", { res.render("home", {
@ -138,77 +154,79 @@ app.get('/home', async (req,res) => {
userinfo: req.session.info, userinfo: req.session.info,
onetimetoken, onetimetoken,
error: errorStrings[req.query.error], error: errorStrings[req.query.error],
s: req.query.s s: req.query.s,
}); });
})
app.post('/spotify/submitsong', async (req,res) => {
if(!req.session.token) return res.redirect('/login');
if(!cacheDb[req.query.token]) return res.redirect(`/home?error=0`);
delete cacheDb[req.query.token];
const songurl = req.body.songurl;
const songuriinfo = require('spotify-uri').parse(songurl);
if(songuriinfo.type !== "track") return res.redirect(`/home?error=1`);
const alreadyExists = await db.has(songuriinfo.id);
if(alreadyExists) return res.redirect(`/home?error=2`);
const formattedURI = require('spotify-uri').formatURI(songuriinfo)
await db.set(songuriinfo.id, {
song_url: songurl,
added_by: req.session.info.user.id,
added_at: Date.now()
}); });
addSongToPlaylist(formattedURI); app.post("/spotify/submitsong", async (req, res) => {
fetch("https://slack.mybot.saahild.com/send-private", { if (!req.session.token) return res.redirect("/login");
method: "POST", if (!cacheDb[req.query.token]) return res.redirect(`/home?error=0`);
body: JSON.stringify({ delete cacheDb[req.query.token];
channel: "C07RE4N7S4B",
text: `:new_spotify: New Song: ${songurl} - added by <@${req.session.info.user.id}>`, const songurl = req.body.songurl;
}),
headers: { const songuriinfo = require("spotify-uri").parse(songurl);
Authorization: process.env.AUTH_FOR_ZEON, if (songuriinfo.type !== "track") return res.redirect(`/home?error=1`);
"Content-Type": "application/json", const alreadyExists = await db.has(songuriinfo.id);
}, if (alreadyExists) return res.redirect(`/home?error=2`);
}).then(r=>r.json()).then(d => { const formattedURI = require("spotify-uri").formatURI(songuriinfo);
await db.set(songuriinfo.id, {
song_url: songurl,
added_by: req.session.info.user.id,
added_at: Date.now(),
});
addSongToPlaylist(formattedURI);
fetch("https://slack.mybot.saahild.com/send-private", { fetch("https://slack.mybot.saahild.com/send-private", {
method: "POST", method: "POST",
body: JSON.stringify({ body: JSON.stringify({
channel: "C07RE4N7S4B", channel: "C07RE4N7S4B",
thread_ts: d.ts, text: `:new_spotify: New Song: ${songurl} - added by <@${req.session.info.user.id}>`,
text: `:thread: Responses about new song here please!`,
}),
headers: {
Authorization: process.env.AUTH_FOR_ZEON,
"Content-Type": "application/json",
},
})
});
if(!process.env.TESTING) {
fetch("https://slack.mybot.saahild.com/send-private", {
method: "POST",
body: JSON.stringify({
channel: "C07RE4N7S4B",
text: `<!subteam^S07RGTY93J8>`,
}), }),
headers: { headers: {
Authorization: process.env.AUTH_FOR_ZEON, Authorization: process.env.AUTH_FOR_ZEON,
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
}) })
} .then((r) => r.json())
res.redirect('/home?s=1') .then((d) => {
}) fetch("https://slack.mybot.saahild.com/send-private", {
app.get('/spotify/link', async (req,res) => { method: "POST",
if(!req.session.info) return res.redirect('/login'); body: JSON.stringify({
if(req.session.info.user.id !== "U07L45W79E1" ) return res.status(401).end("unauthorized"); channel: "C07RE4N7S4B",
res.redirect(getLoginUrl()) thread_ts: d.ts,
}) text: `:thread: Responses about new song here please!`,
}),
headers: {
Authorization: process.env.AUTH_FOR_ZEON,
"Content-Type": "application/json",
},
});
});
if (!process.env.TESTING) {
fetch("https://slack.mybot.saahild.com/send-private", {
method: "POST",
body: JSON.stringify({
channel: "C07RE4N7S4B",
text: `<!subteam^S07RGTY93J8>`,
}),
headers: {
Authorization: process.env.AUTH_FOR_ZEON,
"Content-Type": "application/json",
},
});
}
res.redirect("/home?s=1");
});
app.get("/spotify/link", async (req, res) => {
if (!req.session.info) return res.redirect("/login");
if (req.session.info.user.id !== "U07L45W79E1")
return res.status(401).end("unauthorized");
res.redirect(getLoginUrl());
});
spotifyRoutes(app); spotifyRoutes(app);
app.listen(process.env.PORT || 3000, async () => { app.listen(process.env.PORT || 3000, async () => {
console.log("Example app listening on port 3000!"); console.log("Example app listening on port 3000!");
// if(!await db.has()) // if(!await db.has())
if(getCredentials() !== null) refreshToken(getCredentials().refresh_token); if (getCredentials() !== null) refreshToken(getCredentials().refresh_token);
}); });