Add missing migrations
This commit is contained in:
1 parent
0201d21c38
commit
2d09a4a92c
3 files changed
+90
-3
No files matched your search
@@ -0,0 +1,4 @@
|
||||
-- Add terms/age consent columns expected by the users schema (register flow).
|
||||
ALTER TABLE `users`
|
||||
ADD COLUMN `terms_accepted` TINYINT(1) NOT NULL DEFAULT 0,
|
||||
ADD COLUMN `age_verified` TINYINT(1) NOT NULL DEFAULT 0;
|
||||
@@ -0,0 +1,67 @@
|
||||
import { randomBytes } from "node:crypto";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { drizzle } from "drizzle-orm/mysql2";
|
||||
import { bcrypt, bcryptVerify } from "hash-wasm";
|
||||
import mysql from "mysql2/promise";
|
||||
import * as schema from "@/db/schema";
|
||||
|
||||
const url = new URL(
|
||||
"mysql://cms:HeelM%3Coeikgsdgsccusygcsugy@localhost:3306/habbo",
|
||||
);
|
||||
const pool = mysql.createPool({
|
||||
host: url.hostname,
|
||||
port: Number(url.port) || 3306,
|
||||
user: decodeURIComponent(url.username),
|
||||
password: decodeURIComponent(url.password),
|
||||
database: "habbo",
|
||||
charset: "utf8mb4",
|
||||
});
|
||||
|
||||
const db = drizzle(pool, { schema, mode: "default" });
|
||||
|
||||
async function main() {
|
||||
const hash = await bcrypt({
|
||||
password: "Test1234",
|
||||
salt: randomBytes(16),
|
||||
costFactor: 12,
|
||||
outputType: "encoded",
|
||||
});
|
||||
const uname = "__e2e_test_" + Date.now();
|
||||
try {
|
||||
await db.insert(schema.User).values({
|
||||
username: uname,
|
||||
password: hash,
|
||||
mail: null,
|
||||
accountCreated: Math.floor(Date.now() / 1000),
|
||||
ipRegister: "127.0.0.1",
|
||||
ipCurrent: "127.0.0.1",
|
||||
look: "hr-100-.hd-180-1.ch-255-66.lg-280-110.sh-305-62",
|
||||
});
|
||||
console.log("INSERT OK");
|
||||
|
||||
// Simuleer login-verificatie
|
||||
const [user] = await db
|
||||
.select()
|
||||
.from(schema.User)
|
||||
.where(eq(schema.User.username, uname))
|
||||
.limit(1);
|
||||
if (!user) throw new Error("User not found after insert");
|
||||
const ok = await bcryptVerify({
|
||||
password: "Test1234",
|
||||
hash: user.password,
|
||||
});
|
||||
console.log("LOGIN VERIFY:", ok ? "OK" : "FAILED");
|
||||
} catch (err) {
|
||||
console.error("FAILED:", (err as Error).message);
|
||||
if ((err as { cause?: Error }).cause)
|
||||
console.error("CAUSE:", (err as { cause?: Error }).cause?.message);
|
||||
process.exitCode = 1;
|
||||
} finally {
|
||||
await pool.execute(
|
||||
"DELETE FROM users WHERE username LIKE '\\_\\_e2e\\_test\\_%'",
|
||||
);
|
||||
await pool.end();
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
+19
-3
@@ -29,6 +29,7 @@ const registerSchema = z.object({
|
||||
.regex(/[A-Z]/, "Password must contain at least one uppercase letter")
|
||||
.regex(/[a-z]/, "Password must contain at least one lowercase letter")
|
||||
.regex(/[0-9]/, "Password must contain at least one digit"),
|
||||
passwordConfirmation: z.string(),
|
||||
look: z.string().optional(),
|
||||
});
|
||||
|
||||
@@ -48,6 +49,9 @@ export async function register(
|
||||
.trim()
|
||||
.toLowerCase(),
|
||||
password: String(formData.get("password") ?? "").normalize("NFC"),
|
||||
passwordConfirmation: String(
|
||||
formData.get("password_confirmation") ?? "",
|
||||
).normalize("NFC"),
|
||||
look:
|
||||
String(formData.get("look") ?? "")
|
||||
.normalize("NFC")
|
||||
@@ -60,6 +64,10 @@ export async function register(
|
||||
return parsed.error.issues[0]?.message ?? "Invalid input";
|
||||
}
|
||||
|
||||
if (parsed.data.password !== parsed.data.passwordConfirmation) {
|
||||
return "Passwords do not match";
|
||||
}
|
||||
|
||||
const { username, mail, password, look } = parsed.data;
|
||||
const hasEmail = !!mail;
|
||||
const ip = await clientIp();
|
||||
@@ -124,6 +132,7 @@ export async function register(
|
||||
ipRegister: ip,
|
||||
ipCurrent: ip,
|
||||
look,
|
||||
termsAccepted: raw.termsAccepted,
|
||||
});
|
||||
|
||||
if (hasEmail) {
|
||||
@@ -133,9 +142,16 @@ export async function register(
|
||||
logger.warn("Failed to send verification email after registration");
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
logger.warn("Account creation failed");
|
||||
return "Could not create the account (is the username unique?)";
|
||||
} catch (err) {
|
||||
const code = (err as { cause?: { code?: string } }).cause?.code;
|
||||
if (code === "ER_DUP_ENTRY") {
|
||||
return "That username is already taken";
|
||||
}
|
||||
logger.error("Account creation failed", {
|
||||
code,
|
||||
message: err instanceof Error ? err.message : String(err),
|
||||
});
|
||||
return "Could not create the account. Please try again or contact staff.";
|
||||
}
|
||||
|
||||
redirect("/login?registered=1");
|
||||
|
||||
Reference in new issue
Block a user