Validation: the dump validators refuse the nulls their shared types don't allow (a null title or note on creation, a null URL on edit); a playlist title of spaces is refused and titles are stored trimmed; usernames and emails are checked by the same USERNAME_RE and EMAIL_RE in shared/validation.ts on sign-up, on PATCH /api/users/me (which checked other limits) and in the sign-up form. Mentions are read by shared/mention.ts's mentionedUsernames, which skips code and URLs as Markdown shows them: https://mastodon.social/@bob or a `@bob` in code notified bob; the editor's suggestions derive their trigger from the same pattern instead of a copy. Following an unknown user is a 404 rather than a foreign-key 500, and following a private playlist a 404 rather than a 403 that confirmed it exists. `ws` and `emojibase` are reserved category slugs, since the server answers them before the app. GET /api/users/me no longer turns every error into a 500. Dead code goes: adminOnlyMiddleware, verifyEmailTransport, listUsers, deleteUser with disconnectUser and the force_logout message only it sent, PATCH /api/notifications/:id/read (with markOneRead), isSlugAvailable, the unreachable 500 in fetchComment, and the `if (!ctx.state.user)` checks behind authMiddleware. 214 backend and 627 frontend tests pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
25 lines
799 B
TypeScript
25 lines
799 B
TypeScript
/**
|
|
* Builds the patterns of the search queries' `LIKE`, for the dump, playlist
|
|
* and user searches. A query's `%` and `_` are matched as themselves rather
|
|
* than as wildcards: usernames hold underscores, and "a_b" must not find
|
|
* "axb".
|
|
*
|
|
* @module
|
|
*/
|
|
|
|
/**
|
|
* Returns the pattern matching text that contains `query`, or that starts
|
|
* with it when `where` is `"prefix"`. The SQL must read `LIKE ? ESCAPE '\'`,
|
|
* which the {@link LIKE} fragment spells.
|
|
*/
|
|
export function likePattern(
|
|
query: string,
|
|
where: "anywhere" | "prefix" = "anywhere",
|
|
): string {
|
|
const escaped = query.replace(/[\\%_]/g, "\\$&");
|
|
return where === "prefix" ? `${escaped}%` : `%${escaped}%`;
|
|
}
|
|
|
|
/** Spells `LIKE ? ESCAPE '\'`, for a {@link likePattern} parameter. */
|
|
export const LIKE = "LIKE ? ESCAPE '\\'";
|