Merge tag 'tags/2024.3.3'

This commit is contained in:
jaina heartles 2024-05-14 16:48:25 -07:00
commit df14b213b4
91 changed files with 432 additions and 214 deletions

View file

@ -192,6 +192,7 @@ export class FileServerService {
reply.header('Content-Range', `bytes ${start}-${end}/${file.file.size}`);
reply.header('Accept-Ranges', 'bytes');
reply.header('Content-Length', chunksize);
reply.code(206);
} else {
image = {
data: fs.createReadStream(file.path),
@ -261,7 +262,6 @@ export class FileServerService {
const parts = range.replace(/bytes=/, '').split('-');
const start = parseInt(parts[0], 10);
let end = parts[1] ? parseInt(parts[1], 10) : file.file.size - 1;
console.log(end);
if (end > file.file.size) {
end = file.file.size - 1;
}
@ -431,6 +431,7 @@ export class FileServerService {
reply.header('Content-Range', `bytes ${start}-${end}/${file.file.size}`);
reply.header('Accept-Ranges', 'bytes');
reply.header('Content-Length', chunksize);
reply.code(206);
} else {
image = {
data: fs.createReadStream(file.path),
@ -527,6 +528,9 @@ export class FileServerService {
if (!file.storedInternal) {
if (!(file.isLink && file.uri)) return '204';
const result = await this.downloadAndDetectTypeFromUrl(file.uri);
if (!file.size) {
file.size = (await fs.promises.stat(result.path)).size;
}
return {
...result,
url: file.uri,

View file

@ -35,7 +35,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
private customEmojiService: CustomEmojiService,
) {
super(meta, paramDef, async (ps, me) => {
await this.customEmojiService.addAliasesBulk(ps.ids, ps.aliases);
await this.customEmojiService.addAliasesBulk(ps.ids, ps.aliases.map(a => a.normalize('NFC')));
});
}
}

View file

@ -41,7 +41,7 @@ export const meta = {
export const paramDef = {
type: 'object',
properties: {
name: { type: 'string', pattern: '^[a-zA-Z0-9_]+$' },
name: { type: 'string', pattern: '^[\\p{Letter}\\p{Number}\\p{Mark}_+-]+$' },
fileId: { type: 'string', format: 'misskey:id' },
category: {
type: 'string',
@ -74,18 +74,19 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
private emojiEntityService: EmojiEntityService,
) {
super(meta, paramDef, async (ps, me) => {
const nameNfc = ps.name.normalize('NFC');
const driveFile = await this.driveFilesRepository.findOneBy({ id: ps.fileId });
if (driveFile == null) throw new ApiError(meta.errors.noSuchFile);
const isDuplicate = await this.customEmojiService.checkDuplicate(ps.name);
const isDuplicate = await this.customEmojiService.checkDuplicate(nameNfc);
if (isDuplicate) throw new ApiError(meta.errors.duplicateName);
if (driveFile.user !== null) await this.driveFilesRepository.update(driveFile.id, { user: null });
const emoji = await this.customEmojiService.add({
driveFile,
name: ps.name,
category: ps.category ?? null,
aliases: ps.aliases ?? [],
name: nameNfc,
category: ps.category?.normalize('NFC') ?? null,
aliases: ps.aliases?.map(a => a.normalize('NFC')) ?? [],
host: null,
license: ps.license ?? null,
isSensitive: ps.isSensitive ?? false,

View file

@ -83,15 +83,16 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
throw new ApiError();
}
const nameNfc = emoji.name.normalize('NFC');
// Duplication Check
const isDuplicate = await this.customEmojiService.checkDuplicate(emoji.name);
const isDuplicate = await this.customEmojiService.checkDuplicate(nameNfc);
if (isDuplicate) throw new ApiError(meta.errors.duplicateName);
const addedEmoji = await this.customEmojiService.add({
driveFile,
name: emoji.name,
category: emoji.category,
aliases: emoji.aliases,
name: nameNfc,
category: emoji.category?.normalize('NFC'),
aliases: emoji.aliases?.map(a => a.normalize('NFC')),
host: null,
license: emoji.license,
isSensitive: emoji.isSensitive,

View file

@ -99,7 +99,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
}
if (ps.query) {
q.andWhere('emoji.name like :query', { query: '%' + sqlLikeEscape(ps.query) + '%' })
q.andWhere('emoji.name like :query', { query: '%' + sqlLikeEscape(ps.query.normalize('NFC')) + '%' })
.orderBy('length(emoji.name)', 'ASC');
}

View file

@ -93,17 +93,18 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
//const emojis = await q.limit(ps.limit).getMany();
emojis = await q.orderBy('length(emoji.name)', 'ASC').getMany();
const queryarry = ps.query.match(/\:([a-z0-9_]*)\:/g);
const queryarry = ps.query.match(/:([\p{Letter}\p{Number}\p{Mark}_+-]*):/ug);
if (queryarry) {
emojis = emojis.filter(emoji =>
queryarry.includes(`:${emoji.name}:`),
queryarry.includes(`:${emoji.name.normalize('NFC')}:`),
);
} else {
const queryNfc = ps.query!.normalize('NFC');
emojis = emojis.filter(emoji =>
emoji.name.includes(ps.query!) ||
emoji.aliases.some(a => a.includes(ps.query!)) ||
emoji.category?.includes(ps.query!));
emoji.name.includes(queryNfc) ||
emoji.aliases.some(a => a.includes(queryNfc)) ||
emoji.category?.includes(queryNfc));
}
emojis.splice(ps.limit + 1);
} else {

View file

@ -35,7 +35,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
private customEmojiService: CustomEmojiService,
) {
super(meta, paramDef, async (ps, me) => {
await this.customEmojiService.removeAliasesBulk(ps.ids, ps.aliases);
await this.customEmojiService.removeAliasesBulk(ps.ids, ps.aliases.map(a => a.normalize('NFC')));
});
}
}

View file

@ -35,7 +35,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
private customEmojiService: CustomEmojiService,
) {
super(meta, paramDef, async (ps, me) => {
await this.customEmojiService.setAliasesBulk(ps.ids, ps.aliases);
await this.customEmojiService.setAliasesBulk(ps.ids, ps.aliases.map(a => a.normalize('NFC')));
});
}
}

View file

@ -37,7 +37,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
private customEmojiService: CustomEmojiService,
) {
super(meta, paramDef, async (ps, me) => {
await this.customEmojiService.setCategoryBulk(ps.ids, ps.category ?? null);
await this.customEmojiService.setCategoryBulk(ps.ids, ps.category?.normalize('NFC') ?? null);
});
}
}

View file

@ -41,7 +41,7 @@ export const paramDef = {
type: 'object',
properties: {
id: { type: 'string', format: 'misskey:id' },
name: { type: 'string', pattern: '^[a-zA-Z0-9_]+$' },
name: { type: 'string', pattern: '^[\\p{Letter}\\p{Number}\\p{Mark}_+-]+$' },
fileId: { type: 'string', format: 'misskey:id' },
category: {
type: 'string',
@ -73,6 +73,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
private customEmojiService: CustomEmojiService,
) {
super(meta, paramDef, async (ps, me) => {
const nameNfc = ps.name?.normalize('NFC');
let driveFile;
if (ps.fileId) {
driveFile = await this.driveFilesRepository.findOneBy({ id: ps.fileId });
@ -84,22 +85,22 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
emojiId = ps.id;
const emoji = await this.customEmojiService.getEmojiById(ps.id);
if (!emoji) throw new ApiError(meta.errors.noSuchEmoji);
if (ps.name && (ps.name !== emoji.name)) {
const isDuplicate = await this.customEmojiService.checkDuplicate(ps.name);
if (nameNfc && (nameNfc !== emoji.name)) {
const isDuplicate = await this.customEmojiService.checkDuplicate(nameNfc);
if (isDuplicate) throw new ApiError(meta.errors.sameNameEmojiExists);
}
} else {
if (!ps.name) throw new Error('Invalid Params unexpectedly passed. This is a BUG. Please report it to the development team.');
const emoji = await this.customEmojiService.getEmojiByName(ps.name);
if (!nameNfc) throw new Error('Invalid Params unexpectedly passed. This is a BUG. Please report it to the development team.');
const emoji = await this.customEmojiService.getEmojiByName(nameNfc);
if (!emoji) throw new ApiError(meta.errors.noSuchEmoji);
emojiId = emoji.id;
}
await this.customEmojiService.update(emojiId, {
driveFile,
name: ps.name,
category: ps.category,
aliases: ps.aliases,
name: nameNfc,
category: ps.category?.normalize('NFC'),
aliases: ps.aliases?.map(a => a.normalize('NFC')),
license: ps.license,
isSensitive: ps.isSensitive,
localOnly: ps.localOnly,

View file

@ -83,7 +83,7 @@ export class MastoConverters {
}
return 'unknown';
}
public encodeFile(f: any): Entity.Attachment {
return {
id: f.id,
@ -278,8 +278,9 @@ export class MastoConverters {
reactions: status.emoji_reactions,
emoji_reactions: status.emoji_reactions,
bookmarked: false,
quote: isQuote ? await this.convertReblog(status.reblog) : false,
edited_at: note.updatedAt?.toISOString(),
quote: isQuote ? await this.convertReblog(status.reblog) : null,
// optional chaining cannot be used, as it evaluates to undefined, not null
edited_at: note.updatedAt ? note.updatedAt.toISOString() : null,
});
}
}

View file

@ -43,7 +43,6 @@ html
link(rel='stylesheet' href='/assets/phosphor-icons/bold/style.css')
link(rel='stylesheet' href='/static-assets/fonts/sharkey-icons/style.css')
link(rel='modulepreload' href=`/vite/${clientEntry.file}`)
script(src='/client-assets/libopenmpt.js')
if !config.clientManifestExists
script(type="module" src="/vite/@vite/client")
@ -73,7 +72,6 @@ html
script.
var VERSION = "#{version}";
var CLIENT_ENTRY = "#{clientEntry.file}";
window.libopenmpt = window.Module;
script(type='application/json' id='misskey_meta' data-generated-at=now)
!= metaJson

View file

@ -5,8 +5,8 @@ block vars
- const title = user.name ? `${user.name} (@${user.username})` : `@${user.username}`;
- const url = `${config.url}/notes/${note.id}`;
- const isRenote = note.renote && note.text == null && note.fileIds.length == 0 && note.poll == null;
- const images = (note.files || []).filter(file => file.type.startsWith('image/') && !file.isSensitive)
- const videos = (note.files || []).filter(file => file.type.startsWith('video/') && !file.isSensitive)
- const images = note.cw ? [] : (note.files || []).filter(file => file.type.startsWith('image/') && !file.isSensitive)
- const videos = note.cw ? [] : (note.files || []).filter(file => file.type.startsWith('video/') && !file.isSensitive)
block title
= `${title} | ${instanceName}`