forked from kokonect-link/cherrypick
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e67548b
commit 8a2d6f3
Showing
6 changed files
with
123 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
112 changes: 112 additions & 0 deletions
112
packages/backend/src/server/api/endpoints/admin/emoji/steal.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
/* | ||
* SPDX-FileCopyrightText: syuilo and other misskey, cherrypick contributors | ||
* SPDX-License-Identifier: AGPL-3.0-only | ||
*/ | ||
|
||
import { Inject, Injectable } from '@nestjs/common'; | ||
import { Endpoint } from '@/server/api/endpoint-base.js'; | ||
import type { EmojisRepository } from '@/models/index.js'; | ||
import { IdService } from '@/core/IdService.js'; | ||
import type { DriveFile } from '@/models/entities/DriveFile.js'; | ||
import { DI } from '@/di-symbols.js'; | ||
import { DriveService } from '@/core/DriveService.js'; | ||
import { GlobalEventService } from '@/core/GlobalEventService.js'; | ||
import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js'; | ||
import { ApiError } from '../../../error.js'; | ||
import {IsNull} from "typeorm"; | ||
|
||
export const meta = { | ||
tags: ['admin'], | ||
|
||
requireCredential: true, | ||
requireRolePolicy: 'canManageCustomEmojis', | ||
|
||
errors: { | ||
noSuchEmoji: { | ||
message: 'No such emoji.', | ||
code: 'NO_SUCH_EMOJI', | ||
id: 'e2785b66-dca3-4087-9cac-b93c541cc425', | ||
}, | ||
localEmojiAlreadyExists: { | ||
message: 'Local emoji already exists.', | ||
code: 'LOCAL_EMOJI_ALREADY_EXISTS', | ||
id: 'c7262375-102c-41c6-be6b-4f81166a8a5b', | ||
}, | ||
}, | ||
|
||
res: { | ||
type: 'object', | ||
optional: false, nullable: false, | ||
properties: { | ||
id: { | ||
type: 'string', | ||
optional: false, nullable: false, | ||
format: 'id', | ||
}, | ||
}, | ||
}, | ||
} as const; | ||
|
||
export const paramDef = { | ||
type: 'object', | ||
properties: { | ||
name: { type: 'string' }, | ||
host: { type: 'string' }, | ||
}, | ||
required: ['name', 'host'], | ||
} as const; | ||
|
||
@Injectable() | ||
// eslint-disable-next-line import/no-default-export | ||
export default class extends Endpoint<typeof meta, typeof paramDef> { | ||
constructor( | ||
@Inject(DI.emojisRepository) | ||
private emojisRepository: EmojisRepository, | ||
|
||
private emojiEntityService: EmojiEntityService, | ||
private idService: IdService, | ||
private globalEventService: GlobalEventService, | ||
private driveService: DriveService, | ||
) { | ||
super(meta, paramDef, async (ps, me) => { | ||
const emoji = await this.emojisRepository.findOneBy({ name: ps.name, host: ps.host }); | ||
const localEmoji = await this.emojisRepository.findOneBy({ name: ps.name, host: IsNull() }); | ||
|
||
if (emoji == null) { | ||
throw new ApiError(meta.errors.noSuchEmoji); | ||
} | ||
|
||
if (localEmoji != null) { | ||
throw new ApiError(meta.errors.localEmojiAlreadyExists); | ||
} | ||
|
||
let driveFile: DriveFile; | ||
|
||
try { | ||
driveFile = await this.driveService.uploadFromUrl({ url: emoji.originalUrl, user: null, force: true }); | ||
} catch (e) { | ||
throw new ApiError(); | ||
} | ||
|
||
const copied = await this.emojisRepository.insert({ | ||
id: this.idService.genId(), | ||
updatedAt: new Date(), | ||
name: emoji.name, | ||
host: null, | ||
aliases: [], | ||
originalUrl: driveFile.url, | ||
publicUrl: driveFile.webpublicUrl ?? driveFile.url, | ||
type: driveFile.webpublicType ?? driveFile.type, | ||
license: emoji.license, | ||
}).then(x => this.emojisRepository.findOneByOrFail(x.identifiers[0])); | ||
|
||
this.globalEventService.publishBroadcastStream('emojiAdded', { | ||
emoji: await this.emojiEntityService.packDetailed(copied.id), | ||
}); | ||
|
||
return { | ||
id: copied.id, | ||
}; | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters