force uppercase usernames
This commit is contained in:
parent
ccd4126953
commit
82d8e34560
6 changed files with 1595 additions and 5 deletions
16
website/drizzle/0002_lush_guardian.sql
Normal file
16
website/drizzle/0002_lush_guardian.sql
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
ALTER TABLE "transaction" DROP CONSTRAINT "transaction_recipient_user_id_user_id_fk";
|
||||||
|
--> statement-breakpoint
|
||||||
|
ALTER TABLE "transaction" DROP CONSTRAINT "transaction_sender_user_id_user_id_fk";
|
||||||
|
--> statement-breakpoint
|
||||||
|
ALTER TABLE "coin" ALTER COLUMN "change_24h" SET DATA TYPE numeric(30, 4);--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "transaction" ADD CONSTRAINT "transaction_recipient_user_id_user_id_fk" FOREIGN KEY ("recipient_user_id") REFERENCES "public"."user"("id") ON DELETE set null ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
--> statement-breakpoint
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "transaction" ADD CONSTRAINT "transaction_sender_user_id_user_id_fk" FOREIGN KEY ("sender_user_id") REFERENCES "public"."user"("id") ON DELETE set null ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
1559
website/drizzle/meta/0002_snapshot.json
Normal file
1559
website/drizzle/meta/0002_snapshot.json
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -15,6 +15,13 @@
|
||||||
"when": 1748690470287,
|
"when": 1748690470287,
|
||||||
"tag": "0001_yummy_meggan",
|
"tag": "0001_yummy_meggan",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 2,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1748700252762,
|
||||||
|
"tag": "0002_lush_guardian",
|
||||||
|
"breakpoints": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -80,7 +80,7 @@ export const coin = pgTable("coin", {
|
||||||
currentPrice: decimal("current_price", { precision: 20, scale: 8 }).notNull(), // Price in base currency
|
currentPrice: decimal("current_price", { precision: 20, scale: 8 }).notNull(), // Price in base currency
|
||||||
marketCap: decimal("market_cap", { precision: 30, scale: 2 }).notNull(),
|
marketCap: decimal("market_cap", { precision: 30, scale: 2 }).notNull(),
|
||||||
volume24h: decimal("volume_24h", { precision: 30, scale: 2 }).default("0.00"),
|
volume24h: decimal("volume_24h", { precision: 30, scale: 2 }).default("0.00"),
|
||||||
change24h: decimal("change_24h", { precision: 10, scale: 4 }).default("0.0000"), // Percentage
|
change24h: decimal("change_24h", { precision: 30, scale: 4 }).default("0.0000"), // Percentage
|
||||||
poolCoinAmount: decimal("pool_coin_amount", { precision: 30, scale: 8 }).notNull().default("0.00000000"),
|
poolCoinAmount: decimal("pool_coin_amount", { precision: 30, scale: 8 }).notNull().default("0.00000000"),
|
||||||
poolBaseCurrencyAmount: decimal("pool_base_currency_amount", { precision: 30, scale: 8, }).notNull().default("0.00000000"),
|
poolBaseCurrencyAmount: decimal("pool_base_currency_amount", { precision: 30, scale: 8, }).notNull().default("0.00000000"),
|
||||||
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,9 @@ async function validateInputs(name: string, bio: string, username: string, avata
|
||||||
}
|
}
|
||||||
|
|
||||||
if (username) {
|
if (username) {
|
||||||
const alphanumericRegex = /^[a-zA-Z0-9]+$/;
|
const alphanumericRegex = /^[a-z0-9_]+$/;
|
||||||
if (!alphanumericRegex.test(username)) {
|
if (!alphanumericRegex.test(username)) {
|
||||||
throw error(400, 'Username must contain only letters and numbers');
|
throw error(400, 'Username must contain only lowercase letters, numbers, and underscores');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -56,7 +56,7 @@ export async function POST({ request }) {
|
||||||
const formData = await request.formData();
|
const formData = await request.formData();
|
||||||
const name = formData.get('name') as string;
|
const name = formData.get('name') as string;
|
||||||
const bio = formData.get('bio') as string;
|
const bio = formData.get('bio') as string;
|
||||||
const username = formData.get('username') as string;
|
const username = (formData.get('username') as string)?.toLowerCase();
|
||||||
const avatarFile = formData.get('avatar') as File | null;
|
const avatarFile = formData.get('avatar') as File | null;
|
||||||
|
|
||||||
await validateInputs(name, bio, username, avatarFile);
|
await validateInputs(name, bio, username, avatarFile);
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,19 @@ import { eq } from 'drizzle-orm';
|
||||||
import { isNameAppropriate } from '$lib/server/moderation';
|
import { isNameAppropriate } from '$lib/server/moderation';
|
||||||
|
|
||||||
export async function GET({ url }) {
|
export async function GET({ url }) {
|
||||||
const username = url.searchParams.get('username');
|
const username = url.searchParams.get('username')?.toLowerCase();
|
||||||
if (!username) {
|
if (!username) {
|
||||||
return json({ available: false });
|
return json({ available: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const alphanumericRegex = /^[a-z0-9_]+$/;
|
||||||
|
if (!alphanumericRegex.test(username)) {
|
||||||
|
return json({
|
||||||
|
available: false,
|
||||||
|
reason: 'Username must contain only lowercase letters, numbers, and underscores'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (!(await isNameAppropriate(username))) {
|
if (!(await isNameAppropriate(username))) {
|
||||||
return json({ available: false, reason: 'Inappropriate content' });
|
return json({ available: false, reason: 'Inappropriate content' });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Reference in a new issue