Skip to content

Commit

Permalink
WIP 2
Browse files Browse the repository at this point in the history
  • Loading branch information
willhuff0 committed Nov 14, 2024
1 parent 873c713 commit 3b739fd
Show file tree
Hide file tree
Showing 10 changed files with 6,227 additions and 1,209 deletions.
7,323 changes: 6,137 additions & 1,186 deletions server/package-lock.json

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions server/src/socket_server/firebase_methods.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import firebase from "firebase-admin";

export const ensureUserAuthorized = async (token: any): Promise<[uid: string | undefined, error: string | undefined]> => {
if (!token) {
return [undefined, "User not authenticated!"];
}

var uid: string;
try {
const decodedToken = await firebase.auth().verifyIdToken(token);
uid = decodedToken.uid;
return [uid, undefined];
} catch {
return [undefined, "User id token is invalid!"];
}
}

export const getUserProfile = async (uid: string): Promise<firebase.firestore.DocumentData | undefined> => {
const userProfileSnapshot = await firebase.firestore().collection('users').doc(uid).get();
return userProfileSnapshot.data();
}
5 changes: 3 additions & 2 deletions server/src/socket_server/methods.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { ping } from "./methods/ping";
export { updateLocation } from "./methods/update_location"
export { message } from "./methods/message"
export { nearby } from "./methods/nearby"
export { sendMessage } from "./methods/send_message"
export { getNearbyUsers } from "./methods/get_nearby_users"
export { notifyUpdateProfile } from "./methods/notify_update_profile"
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,22 @@ import { ActiveUser } from "../../types";
import { getActiveUsersInView } from "../regions";
import { ConnectionContext } from "../socket_server";

const filterOutSenderAndConvertToUids = function* (ctx: ConnectionContext, activeUsers: Generator<ActiveUser, any, any>): Generator<string, any, any> {
const filterOutSenderAndConvertToProfiles = function* (ctx: ConnectionContext, activeUsers: Generator<ActiveUser, any, any>): Generator<any, any, any> {
for (const activeUser of activeUsers) {
if (activeUser.uid === ctx.user.uid) continue;
yield activeUser.uid;
yield {
uid: activeUser.uid,
profile: activeUser.profile,
};
}
}

export const nearby = (ctx: ConnectionContext, callback: (nearbyUserUids: string[]) => void): void => {
export const getNearbyUsers = (ctx: ConnectionContext, callback: (nearbyUserUids: string[]) => void): void => {
// Get all users in view
const usersInView = getActiveUsersInView(ctx.user.location);

// Filter out user who send this request and convert ActiveUser objects to uids
const others = filterOutSenderAndConvertToUids(ctx, usersInView);
const others = filterOutSenderAndConvertToProfiles(ctx, usersInView);

// Response to the sender (also convert generator to array)
callback([...others]);
Expand Down
26 changes: 26 additions & 0 deletions server/src/socket_server/methods/notify_update_profile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { getUserProfile } from "../firebase_methods";
import { getActiveUsersInView } from "../regions";
import { ConnectionContext } from "../socket_server";

export const notifyUpdateProfile = async (ctx: ConnectionContext, ack: any): Promise<void> => {
console.log(`[WS] Received notification of user profile update <${ctx.socket.id}>.`);

// pull updated user profile from Firebase
const userProfile = await getUserProfile(ctx.user.uid);
ctx.user.profile.displayName = userProfile.displayName;
ctx.user.profile.profilePicture = userProfile.profilePicture;

const messageToNearbyOthers = {
uid: ctx.user.uid,
profile: ctx.user.profile,
};

// forward notification to all nearby users
const usersInView = getActiveUsersInView(ctx.user.location);
for(const userInView of usersInView) {
if (userInView.uid === ctx.user.uid) continue; // Skip sender
userInView.socket.emit('notifyUpdateProfile', messageToNearbyOthers);
}

if (ack) ack("success");
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { getActiveUsersInView } from "../regions";
import { ConnectionContext } from "../socket_server";

// Called when client sends a message
export const message = (ctx: ConnectionContext, message: Message, ack: any): void => {
export const sendMessage = (ctx: ConnectionContext, message: Message, ack: any): void => {
const recipients = getActiveUsersInView(message.location);
for (const recipient of recipients) {
recipient.socket.emit("message", message);
Expand Down
37 changes: 23 additions & 14 deletions server/src/socket_server/socket_server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ActiveUser } from "../types";
import firebase from "firebase-admin";
import * as methods from "./methods";
import { initRegions, removeActiveUser } from "./regions";
import { ensureUserAuthorized, getUserProfile } from "./firebase_methods";

export type IOSocket = io.Socket<io.DefaultEventsMap, io.DefaultEventsMap, io.DefaultEventsMap, any>

Expand All @@ -29,26 +30,29 @@ export const startSocketServer = () => {
// === Ensure Authorized ===

const token = socket.handshake.auth.token;
const [uid, authError] = await ensureUserAuthorized(token);

if (!token) {
console.error("[WS] User not authenticated!");
socket.emit("User not authenticated!");
if (authError) {
console.error(`[WS] ${authError}`);
socket.emit(authError);
socket.disconnect();
return
}

var uid: string;
try {
const decodedToken = await firebase.auth().verifyIdToken(token);
uid = decodedToken.uid;
console.log(`[WS] User <${uid}> authenticated.`);
} catch {
console.error("[WS] User id token is invalid!");
socket.emit("User id token is invalid!");
console.log(`[WS] User <${uid}> authenticated.`);

//

// === Pull User Profile from Firebase ===

const userProfile = await getUserProfile(uid);
if (userProfile === undefined) {
console.error("[WS] User profile is invalid or has not been created!");
socket.emit("User profile is invalid or has not been created!");
socket.disconnect();
return;
}

//

console.log(`[WS] User <${socket.id}> connected.`);
Expand All @@ -63,6 +67,10 @@ export const startSocketServer = () => {
lat: 0.0,
lon: 0.0,
geohash: "",
},
profile: {
displayName: userProfile.displayName,
profilePicture: userProfile.profilePicture,
}
},
}
Expand All @@ -76,8 +84,9 @@ export const startSocketServer = () => {

socket.on("ping", (ack: any) => methods.ping(ctx, ack));
socket.on("updateLocation", (location: any, ack: any) => methods.updateLocation(ctx, location, ack))
socket.on("message", (message: any, ack: any) => methods.message(ctx, message, ack));
socket.on("nearby", (callback: (nearbyUserUids: string[]) => void) => methods.nearby(ctx, callback));
socket.on("sendMessage", (message: any, ack: any) => methods.sendMessage(ctx, message, ack));
socket.on("getNearbyUsers", (callback: (nearbyUserUids: string[]) => void) => methods.getNearbyUsers(ctx, callback));
socket.on("notifyUpdateProfile", (ack: any) => methods.notifyUpdateProfile(ctx, ack));

//
});
Expand Down
1 change: 1 addition & 0 deletions server/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { Location } from "./types/location";
export { ActiveUser } from "./types/active_user"
export { UserProfile } from "./types/user_profile"
export { Message } from "./types/message"
6 changes: 4 additions & 2 deletions server/src/types/active_user.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { IOSocket } from "../socket_server/socket_server";
import { Location } from "./location";
import { Location, UserProfile } from "../types";

export interface ActiveUser {
socket: IOSocket

uid: string,
location: Location,
}

profile: UserProfile,
}
4 changes: 4 additions & 0 deletions server/src/types/user_profile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface UserProfile {
displayName: string,
profilePicture: number,
}

0 comments on commit 3b739fd

Please sign in to comment.