v3: fixed roles propagation bug, fixed inconsistent file drop zone, fixed chat attachments wrongfully pruned, some visual tweaks
All checks were successful
Build and Publish Docker Image / build-and-push (push) Successful in 41s
All checks were successful
Build and Publish Docker Image / build-and-push (push) Successful in 41s
This commit is contained in:
@@ -46,13 +46,17 @@ export async function authMiddleware<R extends string>(
|
||||
throw new APIException(APIErrorCode.UNAUTHORIZED, 401, "Invalid token");
|
||||
}
|
||||
|
||||
let user;
|
||||
try {
|
||||
getUserById(payload.userId);
|
||||
user = getUserById(payload.userId);
|
||||
} catch {
|
||||
throw new APIException(APIErrorCode.UNAUTHORIZED, 401, "User not found");
|
||||
}
|
||||
|
||||
ctx.state.user = payload;
|
||||
// Trust the live role from the DB, not the role baked into the JWT at login.
|
||||
// Tokens last 7 days, so a role change (e.g. promotion to admin or a demotion)
|
||||
// would otherwise not take effect until the user re-logs in.
|
||||
ctx.state.user = { ...payload, role: user.role };
|
||||
|
||||
await next();
|
||||
}
|
||||
|
||||
@@ -64,16 +64,16 @@ router.get("/ws", async (ctx) => {
|
||||
|
||||
const socket = ctx.upgrade();
|
||||
|
||||
const avatarMime = authPayload
|
||||
? getUserById(authPayload.userId).avatarMime
|
||||
: undefined;
|
||||
// Read the live user so the role reflects the DB, not the (possibly stale)
|
||||
// role embedded in the 7-day JWT.
|
||||
const user = authPayload ? getUserById(authPayload.userId) : undefined;
|
||||
|
||||
const client: WsClient = {
|
||||
socket,
|
||||
userId: authPayload?.userId,
|
||||
username: authPayload?.username,
|
||||
role: authPayload?.role,
|
||||
avatarMime,
|
||||
role: user?.role,
|
||||
avatarMime: user?.avatarMime,
|
||||
};
|
||||
|
||||
// Use addEventListener — more reliable than onopen= with Deno.serve
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
type ChatMessage,
|
||||
} from "../model/interfaces.ts";
|
||||
import { chatMessageRowToApi, db, isChatMessageRow } from "../model/db.ts";
|
||||
import { linkAttachments } from "./attachment-service.ts";
|
||||
|
||||
export const MAX_CHAT_LENGTH = 2000;
|
||||
const DEFAULT_LIMIT = 50;
|
||||
@@ -70,6 +71,9 @@ export function createChatMessage(
|
||||
db.prepare(
|
||||
`INSERT INTO chat_messages (id, user_id, body, created_at, reply_to_id) VALUES (?, ?, ?, ?, ?);`,
|
||||
).run(id, userId, trimmed, createdAt, replyTo);
|
||||
// Claim any pasted/dropped image attachments so the startup cleanup doesn't
|
||||
// purge them as orphans (mirrors dumps/comments/playlists).
|
||||
linkAttachments(trimmed, id);
|
||||
return fetchMessage(id);
|
||||
}
|
||||
|
||||
@@ -115,6 +119,8 @@ export function updateChatMessage(
|
||||
}
|
||||
db.prepare(`UPDATE chat_messages SET body = ?, updated_at = ? WHERE id = ?;`)
|
||||
.run(trimmed, new Date().toISOString(), id);
|
||||
// An edit may introduce a freshly pasted image; claim its attachment too.
|
||||
linkAttachments(trimmed, id);
|
||||
return fetchMessage(id);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user