feat: Added minecraft linking system, closes #29
All checks were successful
Build and Deploy / Deploy Web (push) Successful in 1m5s
Build and Deploy / Deploy Discord Bot (push) Successful in 44s

This commit is contained in:
Xeovalyte 2023-06-05 22:41:48 +02:00
parent d74a51db7f
commit 3eb4453d71
5 changed files with 86 additions and 28 deletions

View File

@ -63,7 +63,7 @@ export default defineEventHandler(async (event) => {
} }
try { try {
await UserModel.updateOne({ 'discord.id': authorizationResponse.id }, { const user = await UserModel.findOneAndUpdate({ 'discord.id': authorizationResponse.id }, {
$set: { $set: {
discord: { discord: {
id: authorizationResponse.id, id: authorizationResponse.id,
@ -74,12 +74,13 @@ export default defineEventHandler(async (event) => {
$setOnInsert: { $setOnInsert: {
username: authorizationResponse.username username: authorizationResponse.username
} }
}, { upsert: true }) }, { upsert: true, returnDocument: 'after' })
const token = jwt.sign({ const token = jwt.sign({
accessToken: tokenResponse.access_token, accessToken: tokenResponse.access_token,
refreshToken: tokenResponse.refresh_token, refreshToken: tokenResponse.refresh_token,
discordId: authorizationResponse.id discordId: authorizationResponse.id,
userId: user._id
}, config.jwtSecret, { expiresIn: tokenResponse.expires_in }) }, config.jwtSecret, { expiresIn: tokenResponse.expires_in })
setCookie(event, 'jwt', token, { httpOnly: true, maxAge: tokenResponse.expires_in * 1000 }) setCookie(event, 'jwt', token, { httpOnly: true, maxAge: tokenResponse.expires_in * 1000 })

View File

@ -1,21 +1,5 @@
export default defineEventHandler(async (event) => { export default defineEventHandler(async (event) => {
const userId: string = event.context.params ? event.context.params.id : '@me' const userId: string = event.context.params ? event.context.params.id : '@me'
if (userId === '@me') { return await getUser(userId, event)
return await getCurrentUser(event)
}
try {
const user = await UserModel.findById(userId)
if (!user) {
throw createError({ statusCode: 400, statusMessage: 'No user was found' })
}
return user
} catch (e) {
console.error('Failed to get user by id', e)
throw createError({ statusCode: 500, statusMessage: 'Failed to get user' })
}
}) })

View File

@ -0,0 +1,23 @@
export default defineEventHandler(async (event) => {
const userId: string = event.context.params ? event.context.params.id : '@me'
const user = await getUser(userId, event)
if (!user.minecraft) {
throw createError({ statusCode: 400, statusMessage: 'Minecraft has not been linked' })
}
const minecraftProfile: any = await $fetch(`https://sessionserver.mojang.com/session/minecraft/profile/${user.minecraft.uuid}`)
try {
user.minecraft = { uuid: user.minecraft.uuid, username: minecraftProfile.name }
user.save()
} catch (e) {
console.error('Failed to update document', e)
throw createError('Failed to update document')
}
return user.minecraft
})

View File

@ -0,0 +1,45 @@
import mongoose from 'mongoose'
export default defineEventHandler(async (event) => {
const { code } = await readBody(event)
const userId: string = event.context.params ? event.context.params.id : '@me'
let whitelistDoc
try {
whitelistDoc = await WhitelistModel.findOne({ code })
if (!whitelistDoc) {
throw createError({ statusCode: 500, statusMessage: 'Whitelist document was not found' })
}
} catch (e) {
console.error('Failed to get whitelist document', e)
throw createError('Failed to get whitelist document')
}
const minecraftProfile: any = await $fetch(`https://sessionserver.mojang.com/session/minecraft/profile/${whitelistDoc.uuid}`)
const user = await getUser(userId, event)
const session = await mongoose.startSession()
session.startTransaction()
try {
whitelistDoc.connected = true
user.minecraft = { uuid: whitelistDoc.uuid, username: minecraftProfile.name }
whitelistDoc.save({ session })
user.save({ session })
await session.commitTransaction()
} catch (e) {
console.error('Failed to update documents', e)
await session.abortTransaction()
throw createError('Failed to update documents')
} finally {
session.endSession()
}
return user.minecraft
})

View File

@ -2,20 +2,20 @@ import * as jwt from 'jsonwebtoken'
interface IDecodedToken { interface IDecodedToken {
discordId: string, discordId: string,
userId: string,
accessToken: string, accessToken: string,
refreshToken: string refreshToken: string
} }
export const getCurrentUser = async (event: any) => { export const getAuth = (event: any) => {
const token = getCookie(event, 'jwt') || null const token = getCookie(event, 'jwt') || null
if (!token) { if (!token) {
throw createError({ statusCode: 401, statusMessage: 'JWT token is invalid' }) throw createError({ statusCode: 401, statusMessage: 'JWT token is invalid' })
} }
let decodedToken
try { try {
decodedToken = jwt.verify(token, config.jwtSecret) as IDecodedToken return jwt.verify(token, config.jwtSecret) as IDecodedToken
} catch (e) { } catch (e) {
console.error('Failed to verify JWT token', e) console.error('Failed to verify JWT token', e)
@ -24,19 +24,24 @@ export const getCurrentUser = async (event: any) => {
statusMessage: 'JWT token is invalid' statusMessage: 'JWT token is invalid'
}) })
} }
}
export const getUser = async (userId: string, event: any) => {
if (userId === '@me') {
const auth = getAuth(event)
userId = auth.userId
}
try { try {
const user = await UserModel.findOne({ 'discord.id': decodedToken.discordId }) const user = await UserModel.findById(userId)
if (!user) { if (!user) {
throw createError({ statusCode: 500, statusMessage: 'User query returned null' }) throw createError({ statusCode: 400, statusMessage: 'No user was found' })
} }
user.accessToken = decodedToken.accessToken
return user return user
} catch (e) { } catch (e) {
console.error('Failed to get user', e) console.error('Failed to get user by id', e)
throw createError({ statusCode: 500, statusMessage: 'Failed to get user' }) throw createError({ statusCode: 500, statusMessage: 'Failed to get user' })
} }