mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2024-11-12 02:17:21 +08:00
292 lines
8 KiB
JavaScript
292 lines
8 KiB
JavaScript
const functions = require("firebase-functions");
|
|
const admin = require("firebase-admin");
|
|
let key = "./serviceAccountKey.json";
|
|
let origin = "http://localhost:5000";
|
|
|
|
if (process.env.GCLOUD_PROJECT === "monkey-type") {
|
|
key = "./serviceAccountKey_live.json";
|
|
origin = "https://monkeytype.com";
|
|
}
|
|
|
|
var serviceAccount = require(key);
|
|
|
|
admin.initializeApp({
|
|
credential: admin.credential.cert(serviceAccount),
|
|
});
|
|
|
|
const db = admin.firestore();
|
|
const auth = admin.auth();
|
|
const fetch = require("node-fetch");
|
|
|
|
exports.changename = functions.https.onCall(async (request, response) => {
|
|
try {
|
|
if (!isUsernameValid(request.name))
|
|
return { status: -1, message: "Name not valid" };
|
|
let taken = await db
|
|
.collection("takenNames")
|
|
.doc(request.name.toLowerCase())
|
|
.get();
|
|
taken = taken.data();
|
|
if (taken === undefined || taken.taken === false) {
|
|
//not taken
|
|
let oldname = admin.auth().getUser(request.uid);
|
|
oldname = (await oldname).name;
|
|
await admin.auth().updateUser(request.uid, { name: request.name });
|
|
await db
|
|
.collection("users")
|
|
.doc(request.uid)
|
|
.set({ name: request.name }, { merge: true });
|
|
await db.collection("takenNames").doc(request.name.toLowerCase()).set(
|
|
{
|
|
taken: true,
|
|
},
|
|
{ merge: true }
|
|
);
|
|
await db.collection("takenNames").doc(oldname.toLowerCase()).delete();
|
|
return { status: 1, message: "Updated" };
|
|
} else {
|
|
return { status: -2, message: "Name taken." };
|
|
}
|
|
} catch (e) {
|
|
return { status: -999, message: "Error: " + e.message };
|
|
}
|
|
});
|
|
|
|
exports.verifyUser = functions.https.onRequest(async (request, response) => {
|
|
response.set("Access-Control-Allow-Origin", origin);
|
|
response.set("Access-Control-Allow-Headers", "*");
|
|
response.set("Access-Control-Allow-Credentials", "true");
|
|
if (request.method === "OPTIONS") {
|
|
// Send response to OPTIONS requests
|
|
response.set("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
|
|
response.set("Access-Control-Allow-Headers", "Authorization,Content-Type");
|
|
response.set("Access-Control-Max-Age", "3600");
|
|
response.status(204).send("");
|
|
return;
|
|
}
|
|
request = request.body.data;
|
|
if (request.uid == undefined) {
|
|
response
|
|
.status(200)
|
|
.send({ data: { status: -1, message: "Need to provide uid" } });
|
|
return;
|
|
}
|
|
try {
|
|
return fetch("https://discord.com/api/users/@me", {
|
|
headers: {
|
|
authorization: `${request.tokenType} ${request.accessToken}`,
|
|
},
|
|
})
|
|
.then((res) => res.json())
|
|
.then(async (res2) => {
|
|
let did = res2.id;
|
|
|
|
if (
|
|
(await db.collection("users").where("discordId", "==", did).get())
|
|
.docs.length > 0
|
|
) {
|
|
response.status(200).send({
|
|
data: {
|
|
status: -1,
|
|
message:
|
|
"This Discord account is already paired to a different Monkeytype account",
|
|
},
|
|
});
|
|
return;
|
|
}
|
|
|
|
await db.collection("users").doc(request.uid).update({
|
|
discordId: did,
|
|
});
|
|
await db.collection("bot-commands").add({
|
|
command: "verify",
|
|
arguments: [did, request.uid],
|
|
executed: false,
|
|
requestTimestamp: Date.now(),
|
|
});
|
|
response
|
|
.status(200)
|
|
.send({ data: { status: 1, message: "Verified", did: did } });
|
|
return;
|
|
})
|
|
.catch((e) => {
|
|
console.error(
|
|
"Something went wrong when trying to verify user " + e.message
|
|
);
|
|
response.status(200).send({ data: { status: -1, message: e.message } });
|
|
return;
|
|
});
|
|
} catch (e) {
|
|
response.status(200).send({ data: { status: -1, message: e } });
|
|
return;
|
|
}
|
|
});
|
|
|
|
async function getUpdatedLbMemory(userdata, mode, mode2, globallb, dailylb) {
|
|
let lbmemory = userdata.lbMemory;
|
|
|
|
if (lbmemory === undefined) {
|
|
lbmemory = {};
|
|
}
|
|
|
|
if (lbmemory[mode + mode2] == undefined) {
|
|
lbmemory[mode + mode2] = {
|
|
global: null,
|
|
daily: null,
|
|
};
|
|
}
|
|
|
|
if (globallb.insertedAt === -1) {
|
|
lbmemory[mode + mode2]["global"] = globallb.insertedAt;
|
|
} else if (globallb.insertedAt >= 0) {
|
|
if (globallb.newBest) {
|
|
lbmemory[mode + mode2]["global"] = globallb.insertedAt;
|
|
} else {
|
|
lbmemory[mode + mode2]["global"] = globallb.foundAt;
|
|
}
|
|
}
|
|
|
|
if (dailylb.insertedAt === -1) {
|
|
lbmemory[mode + mode2]["daily"] = dailylb.insertedAt;
|
|
} else if (dailylb.insertedAt >= 0) {
|
|
if (dailylb.newBest) {
|
|
lbmemory[mode + mode2]["daily"] = dailylb.insertedAt;
|
|
} else {
|
|
lbmemory[mode + mode2]["daily"] = dailylb.foundAt;
|
|
}
|
|
}
|
|
|
|
return lbmemory;
|
|
}
|
|
|
|
exports.updateEmail = functions.https.onCall(async (request, response) => {
|
|
try {
|
|
let previousEmail = await admin.auth().getUser(request.uid);
|
|
|
|
if (previousEmail.email !== request.previousEmail) {
|
|
return { resultCode: -1 };
|
|
} else {
|
|
await admin.auth().updateUser(request.uid, {
|
|
email: request.newEmail,
|
|
emailVerified: false,
|
|
});
|
|
return {
|
|
resultCode: 1,
|
|
};
|
|
}
|
|
} catch (e) {
|
|
console.error(`error updating email for ${request.uid} - ${e}`);
|
|
return {
|
|
resultCode: -999,
|
|
message: e.message,
|
|
};
|
|
}
|
|
});
|
|
|
|
function updateDiscordRole(discordId, wpm) {
|
|
db.collection("bot-commands").add({
|
|
command: "updateRole",
|
|
arguments: [discordId, wpm],
|
|
executed: false,
|
|
requestTimestamp: Date.now(),
|
|
});
|
|
}
|
|
|
|
exports.updateResultTags = functions.https.onCall((request, response) => {
|
|
try {
|
|
let validTags = true;
|
|
request.tags.forEach((tag) => {
|
|
if (!/^[0-9a-zA-Z]+$/.test(tag)) validTags = false;
|
|
});
|
|
if (validTags) {
|
|
return db
|
|
.collection(`users/${request.uid}/results`)
|
|
.doc(request.resultid)
|
|
.update({
|
|
tags: request.tags,
|
|
})
|
|
.then((e) => {
|
|
console.log(
|
|
`user ${request.uid} updated tags for result ${request.resultid}`
|
|
);
|
|
return {
|
|
resultCode: 1,
|
|
};
|
|
})
|
|
.catch((e) => {
|
|
console.error(
|
|
`error while updating tags for result by user ${request.uid}: ${e.message}`
|
|
);
|
|
return { resultCode: -999 };
|
|
});
|
|
} else {
|
|
console.error(`invalid tags for user ${request.uid}: ${request.tags}`);
|
|
return { resultCode: -1 };
|
|
}
|
|
} catch (e) {
|
|
console.error(`error updating tags by ${request.uid} - ${e}`);
|
|
return { resultCode: -999, message: e };
|
|
}
|
|
});
|
|
|
|
exports.unlinkDiscord = functions.https.onRequest((request, response) => {
|
|
response.set("Access-Control-Allow-Origin", origin);
|
|
if (request.method === "OPTIONS") {
|
|
// Send response to OPTIONS requests
|
|
response.set("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
|
|
response.set("Access-Control-Allow-Headers", "Authorization,Content-Type");
|
|
response.set("Access-Control-Max-Age", "3600");
|
|
response.status(204).send("");
|
|
return;
|
|
}
|
|
request = request.body.data;
|
|
try {
|
|
if (request === null || request.uid === undefined) {
|
|
response
|
|
.status(200)
|
|
.send({ data: { status: -999, message: "Empty request" } });
|
|
return;
|
|
}
|
|
return db
|
|
.collection(`users`)
|
|
.doc(request.uid)
|
|
.update({
|
|
discordId: null,
|
|
})
|
|
.then((f) => {
|
|
response.status(200).send({
|
|
data: {
|
|
status: 1,
|
|
message: "Unlinked",
|
|
},
|
|
});
|
|
return;
|
|
})
|
|
.catch((e) => {
|
|
response.status(200).send({
|
|
data: {
|
|
status: -999,
|
|
message: e.message,
|
|
},
|
|
});
|
|
return;
|
|
});
|
|
} catch (e) {
|
|
response.status(200).send({
|
|
data: {
|
|
status: -999,
|
|
message: e,
|
|
},
|
|
});
|
|
return;
|
|
}
|
|
});
|
|
|
|
async function announceLbUpdate(discordId, pos, lb, wpm, raw, acc, con) {
|
|
db.collection("bot-commands").add({
|
|
command: "sayLbUpdate",
|
|
arguments: [discordId, pos, lb, wpm, raw, acc, con],
|
|
executed: false,
|
|
requestTimestamp: Date.now(),
|
|
});
|
|
}
|