Skip to content

Commit

Permalink
fix: username validation
Browse files Browse the repository at this point in the history
  • Loading branch information
rolznz committed Jan 1, 2025
1 parent 6801b54 commit 178dc37
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 9 deletions.
8 changes: 7 additions & 1 deletion app/actions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use server";

import { saveConnectionSecret } from "./db";
import { saveConnectionSecret, UsernameTakenError } from "./db";
import { getAlbyHubUrl, getDailyWalletLimit, getDomain } from "./utils";

export type Reserves = {
Expand Down Expand Up @@ -135,6 +135,12 @@ export async function createWallet(
};
} catch (error) {
console.error(error);

// only expose known errors
if (error instanceof UsernameTakenError) {
return { wallet: undefined, error: error.message };
}

return { wallet: undefined, error: "internal error" };
}
}
Expand Down
6 changes: 6 additions & 0 deletions app/api/wallets/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ export async function POST(request: Request) {
// force lowercase username
if (createWalletRequest.username) {
createWalletRequest.username = createWalletRequest.username.toLowerCase();

if (!/^[a-z0-9]+$/.test(createWalletRequest.username)) {
return new Response("only letters and numbers in username are allowed", {
status: 400,
});
}
}

const { wallet, error } = await createWallet(
Expand Down
34 changes: 26 additions & 8 deletions app/db.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import { PrismaClient } from "@prisma/client";
import { nwc } from "@getalby/sdk";
import { getPublicKey } from "nostr-tools";
import { PrismaClientKnownRequestError } from "@prisma/client/runtime/library";

const prisma = new PrismaClient();

export class UsernameTakenError extends Error {
constructor() {
super("username taken");
}
}

export async function saveConnectionSecret(
username: string | undefined,
connectionSecret: string
Expand All @@ -15,14 +22,25 @@ export async function saveConnectionSecret(
const pubkey = getPublicKey(parsed.secret);
username = username || pubkey.substring(0, 6);

const result = await prisma.connectionSecret.create({
data: {
id: connectionSecret,
username,
pubkey,
},
});
return { username: result.username };
try {
const result = await prisma.connectionSecret.create({
data: {
id: connectionSecret,
username,
pubkey,
},
});
return { username: result.username };
} catch (error) {
console.error("failed to save wallet", error);
if (
error instanceof PrismaClientKnownRequestError &&
error.code === "P2002" // unique constraint
) {
throw new UsernameTakenError();
}
throw error;
}
}

export async function findWalletConnection(query: { username: string }) {
Expand Down

0 comments on commit 178dc37

Please sign in to comment.