forked from atums.world/backend
kinda start index page, add email verify and request route, add session updating
This commit is contained in:
parent
b24b1484cb
commit
cc4ebfbdd0
12 changed files with 287 additions and 0 deletions
94
src/routes/api/auth/email/verify/[code].ts
Normal file
94
src/routes/api/auth/email/verify/[code].ts
Normal file
|
@ -0,0 +1,94 @@
|
|||
import { sql } from "bun";
|
||||
|
||||
import { isUUID } from "@/helpers/char";
|
||||
import { logger } from "@/helpers/logger";
|
||||
import { redis } from "@/helpers/redis";
|
||||
import { sessionManager } from "@/helpers/sessions";
|
||||
|
||||
const routeDef: RouteDef = {
|
||||
method: "POST",
|
||||
accepts: "*/*",
|
||||
returns: "application/json",
|
||||
};
|
||||
|
||||
async function handler(request: ExtendedRequest): Promise<Response> {
|
||||
const { code } = request.params as { code: string };
|
||||
|
||||
if (!code) {
|
||||
return Response.json(
|
||||
{
|
||||
success: false,
|
||||
code: 400,
|
||||
error: "Missing verification code",
|
||||
},
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
|
||||
if (!isUUID(code)) {
|
||||
return Response.json(
|
||||
{
|
||||
success: false,
|
||||
code: 400,
|
||||
error: "Invalid verification code",
|
||||
},
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
const verificationData: unknown = await redis
|
||||
.getInstance()
|
||||
.get("JSON", `email:verify:${code}`);
|
||||
|
||||
if (!verificationData) {
|
||||
return Response.json(
|
||||
{
|
||||
success: false,
|
||||
code: 400,
|
||||
error: "Invalid verification code",
|
||||
},
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
|
||||
const { user_id: userId } = verificationData as {
|
||||
user_id: string;
|
||||
};
|
||||
|
||||
await redis.getInstance().delete("JSON", `email:verify:${code}`);
|
||||
await sql`
|
||||
UPDATE users
|
||||
SET email_verified = true
|
||||
WHERE id = ${userId};`;
|
||||
} catch (error) {
|
||||
logger.error(["Could not verify email:", error as Error]);
|
||||
return Response.json(
|
||||
{
|
||||
success: false,
|
||||
code: 500,
|
||||
error: "Could not verify email",
|
||||
},
|
||||
{ status: 500 },
|
||||
);
|
||||
}
|
||||
|
||||
if (request.session) {
|
||||
await sessionManager.updateSession(
|
||||
request,
|
||||
{ ...request.session, email_verified: true },
|
||||
request.headers.get("User-Agent") || "",
|
||||
);
|
||||
}
|
||||
|
||||
return Response.json(
|
||||
{
|
||||
success: true,
|
||||
code: 200,
|
||||
message: "Email has been verified",
|
||||
},
|
||||
{ status: 200 },
|
||||
);
|
||||
}
|
||||
|
||||
export { handler, routeDef };
|
84
src/routes/api/auth/email/verify/request.ts
Normal file
84
src/routes/api/auth/email/verify/request.ts
Normal file
|
@ -0,0 +1,84 @@
|
|||
import { randomUUIDv7, sql } from "bun";
|
||||
|
||||
import { logger } from "@/helpers/logger";
|
||||
import { redis } from "@/helpers/redis";
|
||||
|
||||
const routeDef: RouteDef = {
|
||||
method: "GET",
|
||||
accepts: "*/*",
|
||||
returns: "application/json",
|
||||
};
|
||||
|
||||
async function handler(request: ExtendedRequest): Promise<Response> {
|
||||
if (!request.session) {
|
||||
return Response.json(
|
||||
{
|
||||
success: false,
|
||||
code: 403,
|
||||
error: "Unauthorized",
|
||||
},
|
||||
{ status: 403 },
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
const [user] = await sql`
|
||||
SELECT email_verified
|
||||
FROM users
|
||||
WHERE id = ${request.session.id}
|
||||
LIMIT 1;`;
|
||||
|
||||
if (!user) {
|
||||
return Response.json(
|
||||
{
|
||||
success: false,
|
||||
code: 404,
|
||||
error: "Unknown user",
|
||||
},
|
||||
{ status: 404 },
|
||||
);
|
||||
}
|
||||
|
||||
if (user.email_verified) {
|
||||
return Response.json(
|
||||
{
|
||||
success: true,
|
||||
code: 200,
|
||||
message: "Email already verified",
|
||||
},
|
||||
{ status: 200 },
|
||||
);
|
||||
}
|
||||
|
||||
const code: string = randomUUIDv7();
|
||||
await redis.getInstance().set(
|
||||
"JSON",
|
||||
`email:verify:${code}`,
|
||||
{ user_id: request.session.id },
|
||||
60 * 60 * 2, // 2 hours
|
||||
);
|
||||
|
||||
// TODO: Send email when email service is implemented
|
||||
|
||||
return Response.json(
|
||||
{
|
||||
success: true,
|
||||
code: 200,
|
||||
message: "Verification email sent",
|
||||
},
|
||||
{ status: 200 },
|
||||
);
|
||||
} catch (error) {
|
||||
logger.error(["Could not send email verification:", error as Error]);
|
||||
return Response.json(
|
||||
{
|
||||
success: false,
|
||||
code: 500,
|
||||
error: "Could not send email verification",
|
||||
},
|
||||
{ status: 500 },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export { handler, routeDef };
|
Loading…
Add table
Add a link
Reference in a new issue