Skip to content

Commit

Permalink
updates to POST /users (#4247)
Browse files Browse the repository at this point in the history
  • Loading branch information
wentokay authored Jun 29, 2023
1 parent b6713df commit 1fc7147
Showing 1 changed file with 88 additions and 84 deletions.
172 changes: 88 additions & 84 deletions backend/native/backpack-api/src/routes/v1/users.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Blockchain,RemoteUserData } from "@coral-xyz/common";
import type { Blockchain, RemoteUserData } from "@coral-xyz/common";
import {
AVATAR_BASE_URL,
BLOCKCHAIN_COMMON,
Expand All @@ -14,6 +14,7 @@ import {
extractUserId,
} from "../../auth/middleware";
import { clearCookie, setJWTCookie, validateJwt } from "../../auth/util";
import { BLOCKCHAINS_NATIVE } from "../../blockchains";
import { REFERRER_COOKIE_NAME } from "../../config";
import { getFriendshipStatus } from "../../db/friendships";
import { getPublicKeyDetails, updatePublicKey } from "../../db/publicKey";
Expand Down Expand Up @@ -136,43 +137,43 @@ router.get("/jwt/xnft", extractUserId, async (req, res) => {
* Create a new user.
*/
router.post("/", async (req, res) => {
const { username, waitlistId, blockchainPublicKeys } =
CreateUserWithPublicKeys.parse(req.body);

// Validate all the signatures
for (const blockchainPublicKey of blockchainPublicKeys) {
const signedMessage = getCreateMessage(blockchainPublicKey.publicKey);
if (
!BLOCKCHAINS_NATIVE[
blockchainPublicKey.blockchain as Blockchain
].validateSignature(
Buffer.from(signedMessage, "utf-8"),
blockchainPublicKey.signature,
blockchainPublicKey.publicKey
)
) {
return res
.status(400)
.json({ msg: `Invalid ${blockchainPublicKey.blockchain} signature` });
try {
const { username, waitlistId, blockchainPublicKeys } =
CreateUserWithPublicKeys.parse(req.body);

// Validate all the signatures
for (const blockchainPublicKey of blockchainPublicKeys) {
const signedMessage = getCreateMessage(blockchainPublicKey.publicKey);
if (
!BLOCKCHAINS_NATIVE[
blockchainPublicKey.blockchain as Blockchain
].validateSignature(
Buffer.from(signedMessage, "utf-8"),
blockchainPublicKey.signature,
blockchainPublicKey.publicKey
)
) {
return res
.status(400)
.json({ msg: `Invalid ${blockchainPublicKey.blockchain} signature` });
}
}
}

// Check for conflicts
const conflictingUsers = await getUsersByPublicKeys(
blockchainPublicKeys.map((b) => ({
blockchain: b.blockchain as Blockchain,
publicKey: b.publicKey,
}))
);
if (conflictingUsers.length > 0) {
// Another user already uses this public key
return res.status(409).json({
msg: "Wallet address is used by another Backpack account",
});
}
// Check for conflicts
const conflictingUsers = await getUsersByPublicKeys(
blockchainPublicKeys.map((b) => ({
blockchain: b.blockchain as Blockchain,
publicKey: b.publicKey,
}))
);
if (conflictingUsers.length > 0) {
// Another user already uses this public key
return res.status(409).json({
msg: "Wallet address is used by another Backpack account",
});
}

const referrerId = await (async () => {
try {
const referrerId = await (async () => {
if (req.cookies[REFERRER_COOKIE_NAME]) {
// Store the referrer if the cookie is valid
return (await getUser(req.cookies[REFERRER_COOKIE_NAME]))?.id as string;
Expand All @@ -187,61 +188,64 @@ router.post("/", async (req, res) => {
}
}
}
} catch (err) {
// TODO: log this failed referral
}
return undefined;
})();

const user = await createUser(
username,
blockchainPublicKeys.map((b) => ({
...b,
// Cast blockchain to correct type
blockchain: b.blockchain as Blockchain,
})),
waitlistId,
referrerId
);
return undefined;
})();

const user = await createUser(
username,
blockchainPublicKeys.map((b) => ({
...b,
// Cast blockchain to correct type
blockchain: b.blockchain as Blockchain,
})),
waitlistId,
referrerId
);

user?.public_keys.map(async ({ blockchain, id }) => {
//TODO: make a bulk, single call here
await updatePublicKey({
userId: user.id,
blockchain,
publicKeyId: id,
user?.public_keys.map(async ({ blockchain, id }) => {
//TODO: make a bulk, single call here
await updatePublicKey({
userId: user.id,
blockchain,
publicKeyId: id,
});
});
});
let jwt: string;
if (user) {
jwt = await setJWTCookie(req, res, user.id as string);
} else {
return res.status(500).json({ msg: "Error creating user account" });
}
let jwt: string;
if (user) {
jwt = await setJWTCookie(req, res, user.id as string);
} else {
return res.status(500).json({ msg: "Error creating user account" });
}

if (process.env.SLACK_WEBHOOK_URL) {
try {
const publicKeyStr = blockchainPublicKeys
.map((b) => `${b.blockchain.substring(0, 3)}: ${b.publicKey}`)
.join(", ");
await fetch(process.env.SLACK_WEBHOOK_URL, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
text: [username, publicKeyStr].join("\n"),
icon_url: `${AVATAR_BASE_URL}/${username}`,
}),
});
} catch (err) {
console.error({ slackWebhook: err });
if (process.env.SLACK_WEBHOOK_URL) {
try {
const publicKeyStr = blockchainPublicKeys
.map((b) => `${b.blockchain.substring(0, 3)}: ${b.publicKey}`)
.join(", ");
await fetch(process.env.SLACK_WEBHOOK_URL, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
text: [username, publicKeyStr].join("\n"),
icon_url: `${AVATAR_BASE_URL}/${username}`,
}),
});
} catch (err) {
console.error({ slackWebhook: err });
}
}
}

clearCookie(res, REFERRER_COOKIE_NAME);
clearCookie(res, REFERRER_COOKIE_NAME);

return res.json({ id: user.id, msg: "ok", jwt });
return res.json({ id: user.id, msg: "ok", jwt });
} catch (err) {
console.error("ERROR", err);
return res
.status(500)
.json({ status: "error", msg: (err as Error).message });
}
});

/**
Expand Down

1 comment on commit 1fc7147

@vercel
Copy link

@vercel vercel bot commented on 1fc7147 Jun 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.