Skip to content
This repository has been archived by the owner on Oct 11, 2024. It is now read-only.

Commit

Permalink
You can now send and accept friend requests
Browse files Browse the repository at this point in the history
  • Loading branch information
emilianya committed Jan 27, 2024
1 parent 1dc2355 commit e382d8c
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 1 deletion.
22 changes: 21 additions & 1 deletion src/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import permissionAssignmentSchema from "./schemas/permissionAssignmentSchema.js"
import roleAssignmentSchema from "./schemas/roleAssignmentSchema.js";
import preferenceSchema from "./schemas/preferenceSchema.js";
import userStatusSchema from "./schemas/userStatusSchema.js";
import friendRequestSchema from "./schemas/friendRequestSchema.js";
import friendSchema from "./schemas/friendSchema.js";

const LOGINDB_URI : string | undefined = process.env.LOGINDB_URI
if (typeof LOGINDB_URI === "undefined") {
Expand All @@ -28,7 +30,7 @@ if (typeof LQDB_URI === "undefined") {
}

const dbEvents = new EventEmitter();
export default { dbEvents, getLoginUsers, getAvatars, getQuarks, getChannels, getMessages, getQuarkOrders, getNicks, getEmotes, getRoles, getPermissionAssignments, getRoleAssignments, getPreferences, getStatuses };
export default { dbEvents, getLoginUsers, getAvatars, getQuarks, getChannels, getMessages, getQuarkOrders, getNicks, getEmotes, getRoles, getPermissionAssignments, getRoleAssignments, getPreferences, getStatuses, getFriendRequests, getFriends };

const logindb = mongoose.createConnection(LOGINDB_URI)

Expand All @@ -52,6 +54,8 @@ let PermissionAssignments
let RoleAssignments
let Preferences
let Statuses
let FriendRequests
let Friends
lqdb.once("open", () => {
Avatars = lqdb.model('avatar', userAvatarSchema);
Quarks = lqdb.model('quark', quarkSchema);
Expand All @@ -65,6 +69,8 @@ lqdb.once("open", () => {
RoleAssignments = lqdb.model('roleAssignments', roleAssignmentSchema, 'roleAssignments');
Preferences = lqdb.model('preferences', preferenceSchema, 'preferences');
Statuses = lqdb.model('statuses', userStatusSchema, 'statuses');
FriendRequests = lqdb.model('friendRequests', friendRequestSchema, 'friendRequests');
Friends = lqdb.model('friends', friendSchema, 'friends');
dbEvents.emit("lq_ready");
})

Expand Down Expand Up @@ -118,4 +124,18 @@ function getPreferences() {

function getStatuses() {
return Statuses;
}

/**
* Warning: this function does not make people want to be your friend
*/
function getFriendRequests() {
return FriendRequests
}

/**
* Warning: this function does not give you friends
*/
function getFriends() {
return Friends
}
3 changes: 3 additions & 0 deletions src/routes/v2/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {ConstantID_SystemUser} from "../../util/ConstantID.js";
import {networkInformation} from "../../index.js";
import preference from "./user/preference.js";
import status, {plainStatus} from "./user/status.js";
import friends from "./user/friends.js";
import path from "path";

const router = express.Router();
Expand Down Expand Up @@ -159,6 +160,8 @@ router.delete("/me/avatar", Auth, async (req, res) => {

router.use("/me/preferences", preference);

router.use("/friends", friends)

router.use("/:id/status", status);
/**
* Find a user by their ID
Expand Down
86 changes: 86 additions & 0 deletions src/routes/v2/user/friends.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import express from "express";
import Auth from "../../../util/Auth.js";
import FeatureFlag from "../../../util/FeatureFlagMiddleware.js";
import db from "../../../db.js";
import Reply from "../../../classes/reply/Reply.js";
import {getUserBulk} from "../channel.js";
import {isValidObjectId} from "mongoose";
import InvalidReplyMessage from "../../../classes/reply/InvalidReplyMessage.js";
import {getNick} from "../../../util/getNickname.js";
import {Scope} from "@sentry/node";

const router = express.Router({
mergeParams: true
});

// Kill switch
router.use(FeatureFlag("LQ_Friends"));

router.use(Auth);

/**
* List friend requests (incoming & outgoing)
*/
router.get("/requests", async (req, res) => {
let FriendRequests = db.getFriendRequests();
let requests = await FriendRequests.find({$or: [{sender: res.locals.user._id}, {receiver: res.locals.user._id}]})
res.reply(new Reply(200, true, {
message: "Here are your friend requests (incoming & outgoing)",
requests
}))
})

/**
* Send or accept friend requests
*/
router.post("/requests/:username", async (req, res) => {
let otherParty = await getUserByName(req.params.username)
if (!otherParty) return res.reply(new InvalidReplyMessage("Invalid user"))
if (otherParty._id.equals(res.locals.user._id)) {
let reply = new Reply(999, false, {
message: "baka"
})
reply.request.cat = "this request is so stupid there isnt a cat to describe it"
res.status(999).json(reply)
}
let Friend = db.getFriends()
let existingFriend = await Friend.findOne({parties: [res.locals.user._id, otherParty._id]});
if (existingFriend) return res.reply(new InvalidReplyMessage("You are already friends with this user"))
let FriendRequest = db.getFriendRequests()
let existingRequest = await FriendRequest.findOne({$or: [{sender: res.locals.user._id, receiver: otherParty._id}, {receiver: res.locals.user._id, sender: otherParty._id}]})
if (existingRequest) {
if (existingRequest.sender.equals(res.locals.user._id)) return res.reply(new InvalidReplyMessage("You have already sent a friend request to this user"));
// ACCEPT FRIEND REQUEST
await FriendRequest.deleteOne({_id: existingRequest._id});
let friend = new Friend({
startedAt: new Date(),
parties: [res.locals.user._id, otherParty._id]
})
await friend.save();
return res.reply(new Reply(200, true, {
message: "Friend request accepted"
}))
} else {
// SEND FRIEND REQUEST
let friendRequest = new FriendRequest({
sender: res.locals.user._id,
receiver: otherParty._id,
reason: req.body.reason && typeof req.body.reason === "string" ? req.body.reason : null
})
await friendRequest.save();
return res.reply(new Reply(201, true, {
message: "Request sent!"
}));
}
})

async function getUserByName(username : string) {
let LoginUser = db.getLoginUsers()
let loginUser = await LoginUser.findOne({username: username})
if (loginUser) return (await getUserBulk([loginUser._id], null))[0]
return null
// This is actually terrible because LITauth usernames arent supposed to be exposed
// FIXME
}

export default router;
6 changes: 6 additions & 0 deletions src/schemas/friendRequestSchema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import * as Mongoose from "mongoose";
export default new Mongoose.Schema({
sender: {type: Mongoose.Types.ObjectId, required: true}, // Who sent it
receiver: {type: Mongoose.Types.ObjectId, required: true}, // Who is it for
reason: {type: String, required: false}, // Free form text field for users to explain why they requested to be friends
});
5 changes: 5 additions & 0 deletions src/schemas/friendSchema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import * as Mongoose from "mongoose";
export default new Mongoose.Schema({
parties: [{type: Object, required: true}], // Who is friends
startedAt: Date, // When did the request get accepted
});

0 comments on commit e382d8c

Please sign in to comment.