Skip to content

Commit

Permalink
Make public pfp and banner a link, not just image name
Browse files Browse the repository at this point in the history
  • Loading branch information
katniny committed Dec 29, 2024
1 parent 8f8ab7e commit 77a3ca7
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 3 deletions.
2 changes: 2 additions & 0 deletions functions/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// just lets firebase know these apis exist
// if you add an API, require it then add to module.exports
const { fetchUser } = require('./public/fetch-user');
const { fetchUserPriv } = require("./server/fetch-user-trans");

module.exports = {
fetchUser,
fetchUserPriv,
};
4 changes: 2 additions & 2 deletions functions/public/fetch-user.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,14 @@ app.get("/", async (req, res) => {
// create an object to store only the specific fields
const filteredUserData = {
achievements: userData.achievements || {},
banner: userData.banner || null,
banner: `https://firebasestorage.googleapis.com/v0/b/chat-transsocial-test.appspot.com/o/images%2Fbanner%2F${user.val()}%2F${userData.banner}?alt=media` || null,
bio: userData.bio || null,
display: userData.display || null,
followers: userData.followers || 0,
following: userData.following || 0,
isSubscribed: userData.isSubscribed || false,
isVerified: userData.isVerified || false,
pfp: userData.pfp || null,
pfp: `https://firebasestorage.googleapis.com/v0/b/chat-transsocial-test.appspot.com/o/images%2Fpfp%2F${user.val()}%2F${userData.pfp}?alt=media` || null,
posts: userData.posts || {},
pronouns: userData.pronouns || null,
suspensionNotes: userData.suspensionNotes || {},
Expand Down
92 changes: 92 additions & 0 deletions functions/server/fetch-user-trans.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
const functions = require("firebase-functions");
const admin = require("firebase-admin");
const rateLimit = require("express-rate-limit");
const cors = require("cors");
const express = require("express");

const isEmulator = process.env.FUNCTIONS_EMULATOR === "true";
if (isEmulator) {
console.log("Running in an emulator environment.");
} else {
console.log("Running in production.");
}

// init firebase admin if not already
if (!admin.apps.length) {
admin.initializeApp();
}
const db = admin.database();

// enable express
const app = express();

// apply cors
app.use(cors({ origin: "*" }));

// apply rate limit: max 100 reqs/hr per domain
const limiter = rateLimit({
windowMs: 60 * 60 * 1000, // 1 hour
max: 100,
keyGenerator: (req) => req.headers["origin"] || req.ip,
message: {
error: "Too many requests, please try again later.",
},
});
app.use(limiter);

app.use((req, res, next) => {
// only allow transs.social to access this data
const allowedDomain = "transs.social";
const requestHost = req.get("host");
const origin = req.headers["origin"];

if (requestHost && !requestHost.includes(allowedDomain) && origin && !origin.includes(allowedDomain)) {
//if (isEmulator && ) {}
}

// only allow GET requests
if (req.method !== "GET") {
return res.status(405).send({ error: "Method not allowed. Only GET requests are allowed." });
}
next();
});

// define route
app.get("/", async (req, res) => {
try {
// get the username from the query params
const userId = req.query.id;
if (!userId) {
return res.status(400).send({
error: "Username is required. If you attempted to use a UID, please use a username instead."
});
}

// fetch user uid from realtime db
const userRef = db.ref(`taken-usernames/${userId}/user`);
const user = await userRef.once("value");

if (!user.exists()) {
return res.status(404).send({ error: "User not found." });
}

// fetch user uid from realtime db
const userDataRef = db.ref(`users/${user.val()}`);
const snapshot = await userDataRef.once("value");

// send user data
res.set("Access-Control-Allow-Origin", "*");
res.set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
res.set("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With");

const userData = snapshot.val();

return res.status(200).send(userData);
} catch (error) {
console.error("Error fetching user: ", error);
return res.status(500).send({ error: "Internal server error." });
}
});

// export the express app wrapped in functions.https.onRequest
exports.fetchUser = functions.https.onRequest(app);
3 changes: 2 additions & 1 deletion testing/public/fetch-user.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>API Test: fetch-user.js (PUBLIC)</title>
<link rel="stylesheet" href="/assets/css/mainSite.css">
</head>

<body>
<body style="margin: 15px;">
<h1>Fetch User Data</h1>
<p>Put in a username to fetch their public data.</p>
<p>~180ms per request (on average)</p>
Expand Down

0 comments on commit 77a3ca7

Please sign in to comment.