remove excess comments
This commit is contained in:
@@ -432,9 +432,8 @@ export const authRouter = createTRPCRouter({
|
||||
};
|
||||
|
||||
if (rememberMe) {
|
||||
cookieOptions.maxAge = 60 * 60 * 24 * 14; // 14 days
|
||||
cookieOptions.maxAge = 60 * 60 * 24 * 14;
|
||||
}
|
||||
// If rememberMe is false, cookie will be session-only (no maxAge)
|
||||
|
||||
setCookie(
|
||||
ctx.event.nativeEvent,
|
||||
@@ -591,7 +590,6 @@ export const authRouter = createTRPCRouter({
|
||||
});
|
||||
}
|
||||
|
||||
// If provider is unknown/null, update it to "email" since they're logging in with password
|
||||
if (
|
||||
!user.provider ||
|
||||
!["email", "google", "github", "apple"].includes(user.provider)
|
||||
@@ -669,7 +667,6 @@ export const authRouter = createTRPCRouter({
|
||||
.setExpirationTime("15m")
|
||||
.sign(secret);
|
||||
|
||||
// Send email
|
||||
const domain = env.VITE_DOMAIN || "https://freno.me";
|
||||
const htmlContent = `<html>
|
||||
<head>
|
||||
@@ -754,7 +751,6 @@ export const authRouter = createTRPCRouter({
|
||||
const { email } = input;
|
||||
|
||||
try {
|
||||
// Check rate limiting
|
||||
const requested = getCookie(
|
||||
ctx.event.nativeEvent,
|
||||
"passwordResetRequested"
|
||||
@@ -777,20 +773,16 @@ export const authRouter = createTRPCRouter({
|
||||
});
|
||||
|
||||
if (res.rows.length === 0) {
|
||||
// Don't reveal if user exists
|
||||
return { success: true, message: "email sent" };
|
||||
}
|
||||
|
||||
const user = res.rows[0] as unknown as User;
|
||||
|
||||
// Create JWT token with user ID (15min expiry)
|
||||
const secret = new TextEncoder().encode(env.JWT_SECRET_KEY);
|
||||
const token = await new SignJWT({ id: user.id })
|
||||
.setProtectedHeader({ alg: "HS256" })
|
||||
.setExpirationTime("15m")
|
||||
.sign(secret);
|
||||
|
||||
// Send email
|
||||
const domain = env.VITE_DOMAIN || "https://freno.me";
|
||||
const htmlContent = `<html>
|
||||
<head>
|
||||
@@ -832,7 +824,6 @@ export const authRouter = createTRPCRouter({
|
||||
|
||||
await sendEmail(email, "password reset", htmlContent);
|
||||
|
||||
// Set rate limit cookie (5 minutes)
|
||||
const exp = new Date(Date.now() + 5 * 60 * 1000);
|
||||
setCookie(
|
||||
ctx.event.nativeEvent,
|
||||
@@ -870,7 +861,6 @@ export const authRouter = createTRPCRouter({
|
||||
}
|
||||
}),
|
||||
|
||||
// Reset password with token
|
||||
resetPassword: publicProcedure
|
||||
.input(
|
||||
z.object({
|
||||
@@ -890,7 +880,6 @@ export const authRouter = createTRPCRouter({
|
||||
}
|
||||
|
||||
try {
|
||||
// Verify JWT token
|
||||
const secret = new TextEncoder().encode(env.JWT_SECRET_KEY);
|
||||
const { payload } = await jwtVerify(token, secret);
|
||||
|
||||
@@ -904,7 +893,6 @@ export const authRouter = createTRPCRouter({
|
||||
const conn = ConnectionFactory();
|
||||
const passwordHash = await hashPassword(newPassword);
|
||||
|
||||
// Get user to check current provider
|
||||
const userRes = await conn.execute({
|
||||
sql: "SELECT provider FROM User WHERE id = ?",
|
||||
args: [payload.id]
|
||||
@@ -919,7 +907,6 @@ export const authRouter = createTRPCRouter({
|
||||
|
||||
const currentProvider = (userRes.rows[0] as any).provider;
|
||||
|
||||
// Only update provider to "email" if it's null, undefined, or not a known OAuth provider
|
||||
if (
|
||||
!currentProvider ||
|
||||
!["google", "github", "apple"].includes(currentProvider)
|
||||
@@ -929,14 +916,12 @@ export const authRouter = createTRPCRouter({
|
||||
args: [passwordHash, "email", payload.id]
|
||||
});
|
||||
} else {
|
||||
// Keep existing OAuth provider, just update password
|
||||
await conn.execute({
|
||||
sql: "UPDATE User SET password_hash = ? WHERE id = ?",
|
||||
args: [passwordHash, payload.id]
|
||||
});
|
||||
}
|
||||
|
||||
// Clear any session cookies
|
||||
setCookie(ctx.event.nativeEvent, "emailToken", "", {
|
||||
maxAge: 0,
|
||||
path: "/"
|
||||
@@ -959,14 +944,12 @@ export const authRouter = createTRPCRouter({
|
||||
}
|
||||
}),
|
||||
|
||||
// Resend email verification
|
||||
resendEmailVerification: publicProcedure
|
||||
.input(z.object({ email: z.string().email() }))
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { email } = input;
|
||||
|
||||
try {
|
||||
// Check rate limiting
|
||||
const requested = getCookie(
|
||||
ctx.event.nativeEvent,
|
||||
"emailVerificationRequested"
|
||||
@@ -998,14 +981,12 @@ export const authRouter = createTRPCRouter({
|
||||
});
|
||||
}
|
||||
|
||||
// Create JWT token (15min expiry)
|
||||
const secret = new TextEncoder().encode(env.JWT_SECRET_KEY);
|
||||
const token = await new SignJWT({ email })
|
||||
.setProtectedHeader({ alg: "HS256" })
|
||||
.setExpirationTime("15m")
|
||||
.sign(secret);
|
||||
|
||||
// Send email
|
||||
const domain = env.VITE_DOMAIN || "https://freno.me";
|
||||
const htmlContent = `<html>
|
||||
<head>
|
||||
@@ -1044,7 +1025,6 @@ export const authRouter = createTRPCRouter({
|
||||
|
||||
await sendEmail(email, "freno.me email verification", htmlContent);
|
||||
|
||||
// Set rate limit cookie
|
||||
setCookie(
|
||||
ctx.event.nativeEvent,
|
||||
"emailVerificationRequested",
|
||||
@@ -1081,7 +1061,6 @@ export const authRouter = createTRPCRouter({
|
||||
}
|
||||
}),
|
||||
|
||||
// Sign out
|
||||
signOut: publicProcedure.mutation(async ({ ctx }) => {
|
||||
setCookie(ctx.event.nativeEvent, "userIDToken", "", {
|
||||
maxAge: 0,
|
||||
|
||||
@@ -162,7 +162,6 @@ export const databaseRouter = createTRPCRouter({
|
||||
requestingUser: ctx.userId
|
||||
});
|
||||
|
||||
// User can only delete their own comments with "user" type
|
||||
if (input.deletionType === "user" && !isOwner && !isAdmin) {
|
||||
throw new TRPCError({
|
||||
code: "FORBIDDEN",
|
||||
@@ -170,7 +169,6 @@ export const databaseRouter = createTRPCRouter({
|
||||
});
|
||||
}
|
||||
|
||||
// Only admins can do admin or database deletion
|
||||
if (
|
||||
(input.deletionType === "admin" ||
|
||||
input.deletionType === "database") &&
|
||||
@@ -184,14 +182,11 @@ export const databaseRouter = createTRPCRouter({
|
||||
|
||||
if (input.deletionType === "database") {
|
||||
console.log("[deleteComment] Performing database deletion");
|
||||
// Full deletion - remove from database
|
||||
// First delete reactions
|
||||
await conn.execute({
|
||||
sql: "DELETE FROM CommentReaction WHERE comment_id = ?",
|
||||
args: [input.commentID]
|
||||
});
|
||||
|
||||
// Then delete the comment
|
||||
await conn.execute({
|
||||
sql: "DELETE FROM Comment WHERE id = ?",
|
||||
args: [input.commentID]
|
||||
@@ -205,7 +200,6 @@ export const databaseRouter = createTRPCRouter({
|
||||
};
|
||||
} else if (input.deletionType === "admin") {
|
||||
console.log("[deleteComment] Performing admin deletion");
|
||||
// Admin delete - replace body with admin message
|
||||
await conn.execute({
|
||||
sql: "UPDATE Comment SET body = ?, commenter_id = ? WHERE id = ?",
|
||||
args: ["[deleted by admin]", "", input.commentID]
|
||||
@@ -219,7 +213,6 @@ export const databaseRouter = createTRPCRouter({
|
||||
};
|
||||
} else {
|
||||
console.log("[deleteComment] Performing user deletion");
|
||||
// User delete - replace body with user message
|
||||
await conn.execute({
|
||||
sql: "UPDATE Comment SET body = ?, commenter_id = ? WHERE id = ?",
|
||||
args: ["[deleted]", "", input.commentID]
|
||||
@@ -249,7 +242,6 @@ export const databaseRouter = createTRPCRouter({
|
||||
.query(async ({ input }) => {
|
||||
try {
|
||||
const conn = ConnectionFactory();
|
||||
// Join with Post table to get post titles along with comments
|
||||
const query = `
|
||||
SELECT c.*, p.title as post_title
|
||||
FROM Comment c
|
||||
@@ -270,10 +262,6 @@ export const databaseRouter = createTRPCRouter({
|
||||
}
|
||||
}),
|
||||
|
||||
// ============================================================
|
||||
// Post Routes
|
||||
// ============================================================
|
||||
|
||||
getPostById: publicProcedure
|
||||
.input(
|
||||
z.object({
|
||||
@@ -288,7 +276,6 @@ export const databaseRouter = createTRPCRouter({
|
||||
async () => {
|
||||
try {
|
||||
const conn = ConnectionFactory();
|
||||
// Single query with JOIN to get post and tags in one go
|
||||
const query = `
|
||||
SELECT p.*, t.value as tag_value
|
||||
FROM Post p
|
||||
@@ -301,7 +288,6 @@ export const databaseRouter = createTRPCRouter({
|
||||
});
|
||||
|
||||
if (results.rows[0]) {
|
||||
// Group tags by post ID
|
||||
const post = results.rows[0];
|
||||
const tags = results.rows
|
||||
.filter((row) => row.tag_value)
|
||||
@@ -339,7 +325,6 @@ export const databaseRouter = createTRPCRouter({
|
||||
try {
|
||||
const conn = ConnectionFactory();
|
||||
|
||||
// Get post by title with JOINs to get all related data in one query
|
||||
const postQuery = `
|
||||
SELECT
|
||||
p.*,
|
||||
@@ -364,7 +349,6 @@ export const databaseRouter = createTRPCRouter({
|
||||
|
||||
const postRow = postResults.rows[0];
|
||||
|
||||
// Return structured data with proper formatting
|
||||
return {
|
||||
post: postRow,
|
||||
comments: [], // Comments are not included in this optimized query - would need separate call if needed
|
||||
@@ -426,7 +410,6 @@ export const databaseRouter = createTRPCRouter({
|
||||
await conn.execute(tagQuery);
|
||||
}
|
||||
|
||||
// Invalidate blog cache
|
||||
cache.deleteByPrefix("blog-");
|
||||
|
||||
return { data: results.lastInsertRowid };
|
||||
@@ -502,7 +485,6 @@ export const databaseRouter = createTRPCRouter({
|
||||
|
||||
const results = await conn.execute({ sql: query, args: params });
|
||||
|
||||
// Handle tags
|
||||
const deleteTagsQuery = `DELETE FROM Tag WHERE post_id = ?`;
|
||||
await conn.execute({
|
||||
sql: deleteTagsQuery,
|
||||
@@ -516,7 +498,6 @@ export const databaseRouter = createTRPCRouter({
|
||||
await conn.execute(tagQuery);
|
||||
}
|
||||
|
||||
// Invalidate blog cache
|
||||
cache.deleteByPrefix("blog-");
|
||||
|
||||
return { data: results.lastInsertRowid };
|
||||
@@ -535,31 +516,26 @@ export const databaseRouter = createTRPCRouter({
|
||||
try {
|
||||
const conn = ConnectionFactory();
|
||||
|
||||
// Delete associated tags first
|
||||
await conn.execute({
|
||||
sql: "DELETE FROM Tag WHERE post_id = ?",
|
||||
args: [input.id.toString()]
|
||||
});
|
||||
|
||||
// Delete associated likes
|
||||
await conn.execute({
|
||||
sql: "DELETE FROM PostLike WHERE post_id = ?",
|
||||
args: [input.id.toString()]
|
||||
});
|
||||
|
||||
// Delete associated comments
|
||||
await conn.execute({
|
||||
sql: "DELETE FROM Comment WHERE post_id = ?",
|
||||
args: [input.id]
|
||||
});
|
||||
|
||||
// Finally delete the post
|
||||
await conn.execute({
|
||||
sql: "DELETE FROM Post WHERE id = ?",
|
||||
args: [input.id]
|
||||
});
|
||||
|
||||
// Invalidate blog cache
|
||||
cache.deleteByPrefix("blog-");
|
||||
|
||||
return { success: true };
|
||||
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
APIError
|
||||
} from "~/server/fetch-utils";
|
||||
|
||||
// Types for commits
|
||||
interface GitCommit {
|
||||
sha: string;
|
||||
message: string;
|
||||
@@ -26,7 +25,6 @@ interface ContributionDay {
|
||||
}
|
||||
|
||||
export const gitActivityRouter = createTRPCRouter({
|
||||
// Get recent commits from GitHub
|
||||
getGitHubCommits: publicProcedure
|
||||
.input(z.object({ limit: z.number().default(3) }))
|
||||
.query(async ({ input }) => {
|
||||
@@ -34,7 +32,6 @@ export const gitActivityRouter = createTRPCRouter({
|
||||
`github-commits-${input.limit}`,
|
||||
10 * 60 * 1000, // 10 minutes
|
||||
async () => {
|
||||
// Get user's repositories sorted by most recently pushed
|
||||
const reposResponse = await fetchWithTimeout(
|
||||
`https://api.github.com/users/MikeFreno/repos?sort=pushed&per_page=10`,
|
||||
{
|
||||
@@ -50,7 +47,6 @@ export const gitActivityRouter = createTRPCRouter({
|
||||
const repos = await reposResponse.json();
|
||||
const allCommits: GitCommit[] = [];
|
||||
|
||||
// Fetch recent commits from each repo
|
||||
for (const repo of repos) {
|
||||
if (allCommits.length >= input.limit * 3) break; // Get extra to sort later
|
||||
|
||||
@@ -69,7 +65,6 @@ export const gitActivityRouter = createTRPCRouter({
|
||||
if (commitsResponse.ok) {
|
||||
const commits = await commitsResponse.json();
|
||||
for (const commit of commits) {
|
||||
// Filter for commits by the authenticated user
|
||||
if (
|
||||
commit.author?.login === "MikeFreno" ||
|
||||
commit.commit?.author?.email?.includes("mike")
|
||||
@@ -91,7 +86,6 @@ export const gitActivityRouter = createTRPCRouter({
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
// Log individual repo failures but continue with others
|
||||
if (
|
||||
error instanceof NetworkError ||
|
||||
error instanceof TimeoutError
|
||||
@@ -108,7 +102,6 @@ export const gitActivityRouter = createTRPCRouter({
|
||||
}
|
||||
}
|
||||
|
||||
// Sort by date and return the most recent
|
||||
allCommits.sort(
|
||||
(a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()
|
||||
);
|
||||
@@ -117,7 +110,6 @@ export const gitActivityRouter = createTRPCRouter({
|
||||
},
|
||||
{ maxStaleMs: 24 * 60 * 60 * 1000 } // Accept stale data up to 24 hours old
|
||||
).catch((error) => {
|
||||
// Final fallback - return empty array if everything fails
|
||||
if (error instanceof NetworkError) {
|
||||
console.error("GitHub API unavailable (network error)");
|
||||
} else if (error instanceof TimeoutError) {
|
||||
@@ -133,7 +125,6 @@ export const gitActivityRouter = createTRPCRouter({
|
||||
});
|
||||
}),
|
||||
|
||||
// Get recent commits from Gitea
|
||||
getGiteaCommits: publicProcedure
|
||||
.input(z.object({ limit: z.number().default(3) }))
|
||||
.query(async ({ input }) => {
|
||||
@@ -141,7 +132,6 @@ export const gitActivityRouter = createTRPCRouter({
|
||||
`gitea-commits-${input.limit}`,
|
||||
10 * 60 * 1000, // 10 minutes
|
||||
async () => {
|
||||
// First, get user's repositories
|
||||
const reposResponse = await fetchWithTimeout(
|
||||
`${env.GITEA_URL}/api/v1/users/Mike/repos?limit=100`,
|
||||
{
|
||||
@@ -157,7 +147,6 @@ export const gitActivityRouter = createTRPCRouter({
|
||||
const repos = await reposResponse.json();
|
||||
const allCommits: GitCommit[] = [];
|
||||
|
||||
// Fetch recent commits from each repo
|
||||
for (const repo of repos) {
|
||||
if (allCommits.length >= input.limit * 3) break; // Get extra to sort later
|
||||
|
||||
@@ -199,7 +188,6 @@ export const gitActivityRouter = createTRPCRouter({
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
// Log individual repo failures but continue with others
|
||||
if (
|
||||
error instanceof NetworkError ||
|
||||
error instanceof TimeoutError
|
||||
@@ -216,7 +204,6 @@ export const gitActivityRouter = createTRPCRouter({
|
||||
}
|
||||
}
|
||||
|
||||
// Sort by date and return the most recent
|
||||
allCommits.sort(
|
||||
(a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()
|
||||
);
|
||||
@@ -225,7 +212,6 @@ export const gitActivityRouter = createTRPCRouter({
|
||||
},
|
||||
{ maxStaleMs: 24 * 60 * 60 * 1000 }
|
||||
).catch((error) => {
|
||||
// Final fallback - return empty array if everything fails
|
||||
if (error instanceof NetworkError) {
|
||||
console.error("Gitea API unavailable (network error)");
|
||||
} else if (error instanceof TimeoutError) {
|
||||
@@ -245,7 +231,6 @@ export const gitActivityRouter = createTRPCRouter({
|
||||
"github-activity",
|
||||
10 * 60 * 1000,
|
||||
async () => {
|
||||
// Use GitHub GraphQL API for contribution data
|
||||
const query = `
|
||||
query($userName: String!) {
|
||||
user(login: $userName) {
|
||||
@@ -287,7 +272,6 @@ export const gitActivityRouter = createTRPCRouter({
|
||||
throw new APIError("GraphQL query failed", 500, "GraphQL Error");
|
||||
}
|
||||
|
||||
// Extract contribution days from the response
|
||||
const contributions: ContributionDay[] = [];
|
||||
const weeks =
|
||||
data.data?.user?.contributionsCollection?.contributionCalendar
|
||||
@@ -327,7 +311,6 @@ export const gitActivityRouter = createTRPCRouter({
|
||||
"gitea-activity",
|
||||
10 * 60 * 1000,
|
||||
async () => {
|
||||
// Get user's repositories
|
||||
const reposResponse = await fetchWithTimeout(
|
||||
`${env.GITEA_URL}/api/v1/user/repos?limit=100`,
|
||||
{
|
||||
@@ -343,7 +326,6 @@ export const gitActivityRouter = createTRPCRouter({
|
||||
const repos = await reposResponse.json();
|
||||
const contributionsByDay = new Map<string, number>();
|
||||
|
||||
// Get commits from each repo (last 3 months to avoid too many API calls)
|
||||
const threeMonthsAgo = new Date();
|
||||
threeMonthsAgo.setMonth(threeMonthsAgo.getMonth() - 3);
|
||||
|
||||
@@ -373,7 +355,6 @@ export const gitActivityRouter = createTRPCRouter({
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
// Log individual repo failures but continue with others
|
||||
if (
|
||||
error instanceof NetworkError ||
|
||||
error instanceof TimeoutError
|
||||
@@ -387,7 +368,6 @@ export const gitActivityRouter = createTRPCRouter({
|
||||
}
|
||||
}
|
||||
|
||||
// Convert to array format
|
||||
const contributions: ContributionDay[] = Array.from(
|
||||
contributionsByDay.entries()
|
||||
).map(([date, count]) => ({ date, count }));
|
||||
|
||||
@@ -47,7 +47,6 @@ import potions from "~/lineage-json/item-route/potions.json";
|
||||
import poison from "~/lineage-json/item-route/poison.json";
|
||||
import staves from "~/lineage-json/item-route/staves.json";
|
||||
|
||||
// Misc data imports
|
||||
import activities from "~/lineage-json/misc-route/activities.json";
|
||||
import investments from "~/lineage-json/misc-route/investments.json";
|
||||
import jobs from "~/lineage-json/misc-route/jobs.json";
|
||||
|
||||
@@ -96,7 +96,6 @@ export const miscRouter = createTRPCRouter({
|
||||
credentials: credentials
|
||||
});
|
||||
|
||||
// Sanitize the title and filename for S3 key (replace spaces with hyphens, remove special chars)
|
||||
const sanitizeForS3 = (str: string) => {
|
||||
return str
|
||||
.replace(/\s+/g, "-") // Replace spaces with hyphens
|
||||
@@ -262,7 +261,6 @@ export const miscRouter = createTRPCRouter({
|
||||
})
|
||||
)
|
||||
.mutation(async ({ input }) => {
|
||||
// Check if contact request was recently sent
|
||||
const contactExp = getCookie("contactRequestSent");
|
||||
let remaining = 0;
|
||||
|
||||
@@ -314,7 +312,6 @@ export const miscRouter = createTRPCRouter({
|
||||
}
|
||||
);
|
||||
|
||||
// Set cookie to prevent spam (60 second cooldown)
|
||||
const exp = new Date(Date.now() + 1 * 60 * 1000);
|
||||
setCookie("contactRequestSent", exp.toUTCString(), {
|
||||
expires: exp,
|
||||
@@ -365,7 +362,6 @@ export const miscRouter = createTRPCRouter({
|
||||
sendDeletionRequestEmail: publicProcedure
|
||||
.input(z.object({ email: z.string().email() }))
|
||||
.mutation(async ({ input }) => {
|
||||
// Check if deletion request was recently sent
|
||||
const deletionExp = getCookie("deletionRequestSent");
|
||||
let remaining = 0;
|
||||
|
||||
@@ -445,7 +441,6 @@ export const miscRouter = createTRPCRouter({
|
||||
)
|
||||
]);
|
||||
|
||||
// Set cookie to prevent spam (60 second cooldown)
|
||||
const exp = new Date(Date.now() + 1 * 60 * 1000);
|
||||
setCookie("deletionRequestSent", exp.toUTCString(), {
|
||||
expires: exp,
|
||||
|
||||
@@ -13,7 +13,6 @@ import type { User } from "~/types/user";
|
||||
import { toUserProfile } from "~/types/user";
|
||||
|
||||
export const userRouter = createTRPCRouter({
|
||||
// Get current user profile
|
||||
getProfile: publicProcedure.query(async ({ ctx }) => {
|
||||
const userId = await getUserID(ctx.event.nativeEvent);
|
||||
|
||||
@@ -41,7 +40,6 @@ export const userRouter = createTRPCRouter({
|
||||
return toUserProfile(user);
|
||||
}),
|
||||
|
||||
// Update email
|
||||
updateEmail: publicProcedure
|
||||
.input(z.object({ email: z.string().email() }))
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
@@ -62,7 +60,6 @@ export const userRouter = createTRPCRouter({
|
||||
args: [email, 0, userId]
|
||||
});
|
||||
|
||||
// Fetch updated user
|
||||
const res = await conn.execute({
|
||||
sql: "SELECT * FROM User WHERE id = ?",
|
||||
args: [userId]
|
||||
@@ -70,7 +67,6 @@ export const userRouter = createTRPCRouter({
|
||||
|
||||
const user = res.rows[0] as unknown as User;
|
||||
|
||||
// Set email cookie for verification flow
|
||||
setCookie(ctx.event.nativeEvent, "emailToken", email, {
|
||||
path: "/"
|
||||
});
|
||||
@@ -78,7 +74,6 @@ export const userRouter = createTRPCRouter({
|
||||
return toUserProfile(user);
|
||||
}),
|
||||
|
||||
// Update display name
|
||||
updateDisplayName: publicProcedure
|
||||
.input(z.object({ displayName: z.string().min(1).max(50) }))
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
@@ -99,7 +94,6 @@ export const userRouter = createTRPCRouter({
|
||||
args: [displayName, userId]
|
||||
});
|
||||
|
||||
// Fetch updated user
|
||||
const res = await conn.execute({
|
||||
sql: "SELECT * FROM User WHERE id = ?",
|
||||
args: [userId]
|
||||
@@ -109,7 +103,6 @@ export const userRouter = createTRPCRouter({
|
||||
return toUserProfile(user);
|
||||
}),
|
||||
|
||||
// Update profile image
|
||||
updateProfileImage: publicProcedure
|
||||
.input(z.object({ imageUrl: z.string() }))
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
@@ -130,7 +123,6 @@ export const userRouter = createTRPCRouter({
|
||||
args: [imageUrl, userId]
|
||||
});
|
||||
|
||||
// Fetch updated user
|
||||
const res = await conn.execute({
|
||||
sql: "SELECT * FROM User WHERE id = ?",
|
||||
args: [userId]
|
||||
@@ -140,7 +132,6 @@ export const userRouter = createTRPCRouter({
|
||||
return toUserProfile(user);
|
||||
}),
|
||||
|
||||
// Change password (requires old password)
|
||||
changePassword: publicProcedure
|
||||
.input(
|
||||
z.object({
|
||||
@@ -202,14 +193,12 @@ export const userRouter = createTRPCRouter({
|
||||
});
|
||||
}
|
||||
|
||||
// Update password
|
||||
const newPasswordHash = await hashPassword(newPassword);
|
||||
await conn.execute({
|
||||
sql: "UPDATE User SET password_hash = ? WHERE id = ?",
|
||||
args: [newPasswordHash, userId]
|
||||
});
|
||||
|
||||
// Clear session cookies (force re-login)
|
||||
setCookie(ctx.event.nativeEvent, "emailToken", "", {
|
||||
maxAge: 0,
|
||||
path: "/"
|
||||
@@ -222,7 +211,6 @@ export const userRouter = createTRPCRouter({
|
||||
return { success: true, message: "success" };
|
||||
}),
|
||||
|
||||
// Set password (for OAuth users who don't have password)
|
||||
setPassword: publicProcedure
|
||||
.input(
|
||||
z.object({
|
||||
@@ -271,14 +259,12 @@ export const userRouter = createTRPCRouter({
|
||||
});
|
||||
}
|
||||
|
||||
// Set password
|
||||
const passwordHash = await hashPassword(newPassword);
|
||||
await conn.execute({
|
||||
sql: "UPDATE User SET password_hash = ? WHERE id = ?",
|
||||
args: [passwordHash, userId]
|
||||
});
|
||||
|
||||
// Clear session cookies (force re-login)
|
||||
setCookie(ctx.event.nativeEvent, "emailToken", "", {
|
||||
maxAge: 0,
|
||||
path: "/"
|
||||
@@ -291,7 +277,6 @@ export const userRouter = createTRPCRouter({
|
||||
return { success: true, message: "success" };
|
||||
}),
|
||||
|
||||
// Delete account (anonymize data)
|
||||
deleteAccount: publicProcedure
|
||||
.input(z.object({ password: z.string() }))
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
@@ -337,7 +322,6 @@ export const userRouter = createTRPCRouter({
|
||||
});
|
||||
}
|
||||
|
||||
// Anonymize user data (don't hard delete)
|
||||
await conn.execute({
|
||||
sql: `UPDATE User SET
|
||||
email = ?,
|
||||
@@ -350,7 +334,6 @@ export const userRouter = createTRPCRouter({
|
||||
args: [null, 0, null, "user deleted", null, null, userId]
|
||||
});
|
||||
|
||||
// Clear session cookies
|
||||
setCookie(ctx.event.nativeEvent, "emailToken", "", {
|
||||
maxAge: 0,
|
||||
path: "/"
|
||||
|
||||
Reference in New Issue
Block a user