1
0
Fork 0

backend structure update

- removed unnecessry data from express user
- changed database arguments and return types
- made `/api/user-data` get data from db instead of express user
This commit is contained in:
Kim, Jimin 2022-02-27 10:44:42 +09:00
parent 5878e4dd29
commit 695f75d363
5 changed files with 79 additions and 50 deletions

View file

@ -6,41 +6,53 @@ interface DatabaseResult {
error?: string
}
interface UserResult extends DatabaseResult {
user?: Express.User | FirebaseFirestore.DocumentData
}
export default {
async findUser(uid: string): Promise<UserResult> {
/**
* Checks if a user exists in the database
*
* @param {string} uid - discord user id
*/
async findUser(uid: string): Promise<DatabaseResult> {
try {
const user = await admin.firestore().collection("users").doc(uid).get()
if (user.exists) {
return {
success: true,
user: user.data(),
}
} else {
if (!user.exists) {
return {
success: false,
error: `user with uid ${uid} does not exist`,
}
}
return { success: true }
} catch (error) {
return { success: false, error: error.message }
}
},
async newUser(profile: Express.User): Promise<UserResult> {
try {
await firestore().doc(`/users/${profile.id}`).set({
id: profile.id,
avatar: profile.avatar,
username: profile.username,
discriminator: profile.discriminator,
})
/**
* Reads user data from the database
*
* @param {string} uid - discord user id
*/
async getUser(uid: string): Promise<DBUser> {
const result = await admin.firestore().collection("users").doc(uid).get()
if (!result.exists) throw new Error(`user with uid ${uid} does not exist`)
return { success: true, user: profile }
const data = result.data()
if (!data) throw new Error("User was found but failed to read the data.")
return data as DBUser
},
/**
* Create a new entry in the database
*
* @param {DBUser} data - User data to create
*/
async newUser(data: DBUser): Promise<DatabaseResult> {
try {
await firestore().doc(`/users/${data.id}`).set(data)
return { success: true }
} catch (error) {
logger.error("Error creating user", error)
@ -48,14 +60,14 @@ export default {
}
},
async updateUser(profile: Express.User): Promise<UserResult> {
await firestore().doc(`/users/${profile.id}`).update({
id: profile.id,
avatar: profile.avatar,
username: profile.username,
discriminator: profile.discriminator,
})
/**
* Update user data
*
* @param {Partial<DBUser>} data - Data to update
*/
async updateUser(data: Partial<DBUser>): Promise<DatabaseResult> {
await firestore().doc(`/users/${data.id}`).update(data)
return { success: true, user: profile }
return { success: true }
},
}

View file

@ -8,18 +8,21 @@ import passport from "passport"
import config from "../config.json"
export default (app: Express): void => {
// start login (redirects to /api/auth)
app.get(
config.pathPrefix + "/login",
passport.authenticate("discord", { scope: config.scopes })
)
app.get(config.pathPrefix + "/logout", (req, res) => {
req.logout()
res.redirect("/")
})
// authenticates login (redirects to /)
app.get(
config.pathPrefix + "/auth",
passport.authenticate("discord", { successRedirect: "/" })
)
// logs out the user
app.get(config.pathPrefix + "/logout", (req, res) => {
req.logout()
res.redirect("/")
})
}

View file

@ -3,6 +3,7 @@
*/
import { Express, Request, Response, NextFunction } from "express"
import database from "../API/database"
import config from "../config.json"
@ -12,6 +13,9 @@ const checkIfLoggedIn = (req: Request, res: Response, next: NextFunction) => {
}
export default (app: Express): void => {
/**
* Get user data from google firebase firestore
*/
app.get(
config.pathPrefix + "/user-data",
checkIfLoggedIn,
@ -19,7 +23,7 @@ export default (app: Express): void => {
res.setHeader("Cache-Control", "private")
req.user
? res.status(200).send(req.user)
? res.status(200).send(await database.getUser(req.user.id))
: res.status(500).send("Failed to get user")
}
)

View file

@ -15,10 +15,10 @@ passport.serializeUser((user, done) => {
passport.deserializeUser(async (id: string, done) => {
try {
const user = await database.findUser(id)
const result = await database.findUser(id)
if (user.success) {
done(null, user.user as Express.User)
if (result.success) {
done(null, { id })
} else {
done(new Error("Failed to get user from database"))
}
@ -44,17 +44,22 @@ passport.use(
async (_accessToken, _refreshToken, profile, done) => {
try {
const user = await database.findUser(profile.id)
const result = await database.findUser(profile.id)
if (!user.success) {
database.newUser(profile as Express.User)
const data = {
avatar: profile.avatar || undefined,
discriminator: profile.discriminator,
id: profile.id,
username: profile.username,
}
if (user.user) {
await database.updateUser(profile as Express.User)
if (result.success) {
await database.updateUser(data)
} else {
database.newUser(data)
}
done(null, profile as Express.User)
done(null, { id: profile.id })
} catch (error) {
logger.error("Error creating a user", error)
}

View file

@ -1,13 +1,18 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import PassportDiscord from "passport-discord"
declare global {
namespace Express {
export interface User extends PassportDiscord.Profile {
token: string
refreshToken: string
// user data for the express server
export interface User {
id: string
}
}
// user data in the google firebase firestore DB
export interface DBUser {
id: string // discord user id
avatar?: string // discord avatar hash
discriminator: string // 4 digit discord discriminator
username: string // discord username
}
}
export {}