Compare commits

..

No commits in common. "3fc984ad2d0d8da4eacf319b41a09109a47c0934" and "76b4e4ee0875823ac4cdaaad3b89d4b4d082ce32" have entirely different histories.

18 changed files with 92 additions and 200 deletions

View file

@ -12,7 +12,7 @@ password: "Kata sandi"
forgotPassword: "Lupa Kata Sandi"
fetchingAsApObject: "Mengambil data dari Fediverse..."
ok: "OK"
gotIt: "Saya mengerti!"
gotIt: "Saya mengerti"
cancel: "Batalkan"
renotedBy: "direnote oleh {user}"
noNotes: "Tidak ada catatan"
@ -24,7 +24,7 @@ otherSettings: "Pengaturan lainnya"
openInWindow: "Buka di jendela"
profile: "Profil"
timeline: "Linimasa"
noAccountDescription: "Pengguna ini belum menulis biodata mereka."
noAccountDescription: "Pengguna ini belum menulis bio"
login: "Masuk"
loggingIn: "Sedang masuk"
logout: "Keluar"
@ -62,8 +62,8 @@ files: "Berkas"
download: "Unduh"
driveFileDeleteConfirm: "Hapus {name}? Catatan dengan berkas terkait juga akan terhapus."
unfollowConfirm: "Berhenti mengikuti {name}?"
exportRequested: "Anda telah meminta ekspor. Ini mungkin memerlukan waktu beberapa\
\ saat. File ini akan ditambahkan ke Drive Anda setelah selesai."
exportRequested: "Kamu telah meminta ekspor. Ini akan memakan waktu sesaat. Setelah\
\ ekspor selesai, berkas yang dihasilkan akan ditambahkan ke Drive"
importRequested: "Kamu telah meminta impor. Ini akan memakan waktu sesaat."
lists: "Daftar"
note: "Catat"
@ -100,8 +100,8 @@ clickToShow: "Klik untuk melihat"
sensitive: "Konten sensitif"
add: "Tambahkan"
reaction: "Reaksi"
reactionSettingDescription2: "Seret untuk menyusun ulang, klik untuk menghapus, tekan\
\ \"+\" untuk menambahkan."
reactionSettingDescription2: "Geser untuk memindah urutkan, klik untuk menghapus,\
\ tekan \"+\" untuk menambahkan"
attachCancel: "Hapus lampiran"
markAsSensitive: "Tandai sebagai konten sensitif"
unmarkAsSensitive: "Hapus tanda konten sensitif"
@ -193,10 +193,10 @@ blockedUsers: "Pengguna yang diblokir"
noUsers: "Tidak ada pengguna"
editProfile: "Sunting profil"
noteDeleteConfirm: "Apakah kamu yakin ingin menghapus catatan ini?"
pinLimitExceeded: "Anda tidak dapat menyematkan catatan lagi."
pinLimitExceeded: "Kamu tidak dapat menyematkan catatan lagi"
intro: "Instalasi FoundKey telah selesai! Mohon untuk membuat pengguna admin."
done: "Selesai"
processing: "Pemrosesan..."
processing: "Memproses"
preview: "Pratinjau"
default: "Bawaan"
noCustomEmojis: "Tidak ada emoji kustom"
@ -210,7 +210,7 @@ publishing: "Sedang menyiarkan langsung"
notResponding: "Tidak ada respon"
changePassword: "Ubah kata sandi"
security: "Keamanan"
retypedNotMatch: "Input tidak cocok."
retypedNotMatch: "Input tidak sama"
currentPassword: "Kata sandi saat ini"
newPassword: "Kata sandi baru"
newPasswordRetype: "Ulangi kata sandi baru"
@ -237,7 +237,7 @@ fromUrl: "Dari URL"
uploadFromUrl: "Unggah dari URL"
uploadFromUrlDescription: "URL berkas yang ingin kamu unggah"
uploadFromUrlRequested: "Pengunggahan telah diminta"
uploadFromUrlMayTakeTime: "Mungkin diperlukan waktu hingga unggahan selesai."
uploadFromUrlMayTakeTime: "Membutuhkan beberapa waktu hingga pengunggahan selesai"
explore: "Jelajahi"
messageRead: "Telah dibaca"
noMoreHistory: "Tidak ada sejarah lagi"
@ -403,7 +403,7 @@ newMessageExists: "Kamu mendapatkan pesan baru"
onlyOneFileCanBeAttached: "Kamu hanya dapat melampirkan satu berkas ke dalam pesan"
signinRequired: "Silahkan login"
invitationCode: "Kode undangan"
checking: "Memeriksa..."
checking: "Memeriksa"
available: "Tersedia"
unavailable: "Tidak tersedia"
usernameInvalidFormat: "Hanya dapat menerima karakter a-z, A-Z dan angka 0-9."
@ -445,10 +445,11 @@ showFeaturedNotesInTimeline: "Tampilkan catatan yang diunggulkan di linimasa"
objectStorage: "Object Storage"
useObjectStorage: "Gunakan object storage"
objectStorageBaseUrl: "Base URL"
objectStorageBaseUrlDesc: "URL yang digunakan sebagai referensi. Tentukan URL CDN\
\ atau Proksi Anda jika Anda menggunakan keduanya.\nUntuk S3 gunakan 'https://<bucket>.s3.amazonaws.com'\
\ dan untuk GCS atau layanan yang setara gunakan 'https://storage.googleapis.com/<bucket>',\
\ dst."
objectStorageBaseUrlDesc: "Prefix URL digunakan untuk mengkonstruksi URL ke object\
\ (media) referencing. Tentukan URL jika kamu menggunakan CDN atau Proxy, jika tidak\
\ tentukan alamat yang dapat diakses secara publik sesuai dengan panduan dari layanan\
\ yang akan kamu gunakan, contohnya. 'https://<bucket>.s3.amazonaws.com' untuk AWS\
\ S3, dan 'https://storage.googleapis.com/<bucket>' untuk GCS."
objectStorageBucket: "Bucket"
objectStorageBucketDesc: "Mohon tentukan nama bucket yang digunakan pada layanan yang\
\ telah dikonfigurasi."
@ -646,8 +647,8 @@ contact: "Kontak"
useSystemFont: "Gunakan font bawaan sistem operasi"
clips: "Klip"
makeExplorable: "Buat akun tampil di \"Jelajahi\""
makeExplorableDescription: "Jika Anda menonaktifkannya, akun Anda tidak akan muncul\
\ di bagian \"Jelajahi\"."
makeExplorableDescription: "Jika kamu mematikan ini, akun kamu tidak akan muncul di\
\ bagian \"Jelajahi:"
showGapBetweenNotesInTimeline: "Tampilkan jarak diantara catatan pada linimasa"
duplicate: "Duplikat"
left: "Kiri"
@ -758,7 +759,7 @@ ffVisibility: "Visibilitas Mengikuti/Pengikut"
ffVisibilityDescription: "Mengatur siapa yang dapat melihat pengikutmu dan yang kamu\
\ ikuti."
continueThread: "Lihat lanjutan thread"
deleteAccountConfirm: "Ini akan menghapuskan akun {handle} secara permanen. Lanjutkan?"
deleteAccountConfirm: "Akun akan dihapus. Apakah kamu yakin?"
incorrectPassword: "Kata sandi salah."
voteConfirm: "Konfirmasi suara kamu untuk ({choice})"
hide: "Sembunyikan"
@ -1078,7 +1079,7 @@ _auth:
shareAccess: "Apakah kamu ingin mengijinkan \"{name}\" untuk mengakses akun ini?"
shareAccessAsk: "Apakah kamu ingin mengijinkan aplikasi ini untuk mengakses akun\
\ kamu?"
permissionAsk: "Aplikasi ini meminta izin berikut ini"
permissionAsk: "Aplikasi ini membutuhkan beberapa ijin, yaitu:"
pleaseGoBack: "Mohon kembali ke aplikasi kamu"
callback: "Mengembalikan kamu ke aplikasi"
denied: "Akses ditolak"
@ -1262,7 +1263,7 @@ _notification:
youWereFollowed: "Mengikuti kamu"
youReceivedFollowRequest: "Kamu menerima permintaan mengikuti"
yourFollowRequestAccepted: "Permintaan mengikuti kamu telah diterima"
youWereInvitedToGroup: "{userName} mengundang Anda ke grup"
youWereInvitedToGroup: "Telah diundang ke grup"
pollEnded: "Hasil Kuesioner telah keluar"
emptyPushNotificationMessage: "Pembaruan notifikasi dorong"
_types:

View file

@ -1295,7 +1295,7 @@ _remoteInteract:
description: 今すぐにこのアクションを実行することはできません。あなたのインスタンス上で、またはログインして行う必要があるかもしれません。
movedTo: このユーザーは {handle} に引っ越しました。
uploadFailedDescription: ファイルをアップロードできませんでした。
uploadFailedSize: ファイルサイズが大きすぎるためアップロードできません。
uploadFailedSize: このファイルは大きすぎるためアップロードできません。
uploadFailed: アップロード失敗
showAttachedNotes: 添付ノートを表示
attachedToNotes: このファイルが添付されたノート

View file

@ -181,15 +181,14 @@ clearCachedFiles: "Очистить кэш"
clearCachedFilesConfirm: "Удалить все закэшированные файлы с других сайтов?"
blockedInstances: "Заблокированные инстансы"
blockedInstancesDescription: "Введите список инстансов, которые хотите заблокировать.\
\ Они больше не смогут обмениваться с вашим инстансом. Не-ASCII доменные имена должны\
\ быть переведены в punycode. Субдомены тоже будут заблокированы"
\ Они больше не смогут обмениваться с вашим инстансом."
muteAndBlock: "Скрытие и блокировка"
mutedUsers: "Скрытые пользователи"
blockedUsers: "Заблокированные пользователи"
noUsers: "Нет ни одного пользователя"
editProfile: "Редактировать профиль"
noteDeleteConfirm: "Вы хотите удалить эту заметку?"
pinLimitExceeded: "Нельзя закрепить ещё больше заметок."
pinLimitExceeded: "Нельзя закрепить ещё больше заметок"
intro: "Установка FoundKey завершена! А теперь создайте учетную запись администратора."
done: "Готово"
processing: "Обработка"
@ -723,7 +722,7 @@ misskeyUpdated: "FoundKey обновился!"
whatIsNew: "Что новенького?"
translate: "Перевод"
translatedFrom: "Перевод. Язык оригинала — {x}"
accountDeletionInProgress: "В настоящее время выполняется удаление учетной записи."
accountDeletionInProgress: "В настоящее время выполняется удаление учетной записи"
usernameInfo: "Имя, которое отличает вашу учетную запись от других на этом сервере.\
\ Вы можете использовать алфавит (a~z, A~Z), цифры (0~9) или символы подчеркивания\
\ (_). Имена пользователей не могут быть изменены позже."
@ -750,7 +749,7 @@ ffVisibility: "Видимость подписок и подписчиков"
ffVisibilityDescription: "Здесь можно настроить, кто будет видеть ваши подписки и\
\ подписчиков."
continueThread: "Показать следующие ответы"
deleteAccountConfirm: "Учётная запись {handle} будет безвозвратно удалена. Подтверждаете?"
deleteAccountConfirm: "Учётная запись будет безвозвратно удалена. Подтверждаете?"
incorrectPassword: "Пароль неверен."
voteConfirm: "Отдать голос за «{choice}»?"
hide: "Спрятать"
@ -1269,81 +1268,3 @@ _deck:
mentions: "Упоминания"
direct: "Личное"
_services: {}
botFollowRequiresApproval: Запросы на подписку от аккаунтов помеченных как бот требуют
подтверждения
showLess: Показать меньше
exportAll: Экспортировать всё
exportSelected: Экспортировать выбранное
cannotAttachFileWhenAccountSwitched: Вы не можете прикрепить файл, перейдя в другую
учетную запись.
cannotSwitchAccountWhenFileAttached: Вы не можете переключать учетные записи, пока
файлы прикреплены.
deleteAccount: Удалить аккаунт
isSystemAccount: Учетная запись, созданная системой и автоматически управляемая ею.
oneDay: Один день
cropImage: Обрезать изображение
documentation: Документация
movedTo: Этот пользователь перешел на {handle}.
typeToConfirm: Пожалуйста введите {x} чтобы подтвердить
rateLimitExceeded: Лимит превышен
numberOfPageCache: Количество кэшированных страниц
numberOfPageCacheDescription: Увеличение этого числа повысит удобство для пользователей,
но приведет к увеличению нагрузки на сервер, а также к использованию большего объема
памяти.
file: Файл
unclip: Удалить из подборки
translationSettings: Настройки перевода
translationService: Служба перевода
threadMuteNotificationsDesc: Выберите уведомления, которые вы хотите просмотреть в
этом треде. Также применяются глобальные настройки уведомлений. Отключение имеет
приоритет.
reflectMayTakeTime: Это может занять некоторое время чтобы вступило в силу.
failedToFetchAccountInformation: Не удалось получить информацию о аккаунте
instanceDefaultThemeDescription: Введите код темы в формате объекта.
tenMinutes: 10 минут
oneHour: Один час
oneWeek: Одна неделя
cropImageAsk: Вы хотите обрезать это изображение?
recentNHours: Последние {n} часов
recentNDays: Последние {n} дней
confirmToUnclipAlreadyClippedNote: Эта заметка уже является частью подборки "{name}".
Вы хотите вместо этого удалить это из этой подборки?
noEmailServerWarning: Сервер электронной почты не настроен.
setTag: Установить метку
addTag: Добавить метку
removeTag: Удалить метку
externalCssSnippets: Несколько фрагментов CSS для вашего вдохновения (не управляются
FoundKey)
oauthErrorGoBack: Произошла ошибка при попытке аутентификации стороннего приложения.
Пожалуйста, вернитесь и попробуйте еще раз.
appAuthorization: Авторизация приложения
noPermissionsRequested: (Никаких разрешений не требуется.)
selectMode: Выберите несколько
selectAll: Выбрать все
setCategory: Установить категорию
thereIsUnresolvedAbuseReportWarning: Есть нерасмотренные жалобы.
recommended: Рекомендовано
check: Проверка
unlimited: Неограниченный
mutePeriod: Длительность глушения
uploadFailed: Загрузка не удалась
uploadFailedDescription: Файл не может быть загружен.
uploadFailedSize: Файл слишком большой для загрузки.
renoteUnmute: Показать репосты
stopActivityDeliveryDescription: Локальная активнось не будет отправлена на этот сервер.
Получение активностей работает как раньше.
renoteMute: Скрыть репосты
unrenoteAllConfirm: Вы уверены что хотите отменить все репосты данной замети?
unrenoteAll: Отменить все репосты
blockThisInstanceDescription: Локальная активность не будет отправлена на этот сервер.
Активность этого сервера будет выброшена.
attachedToNotes: Заметки с этим файлом
showAttachedNotes: Показать заметки с этим файлом
signinHistoryExpires: Данные о прошлых попытках войти будут автоматически удалены
после 60 дней для соблюдения правил конфиденциальности.
deleteAllFiles: Удалить все файлы
federateBlocks: Федерировать блоки
federateBlocksDescription: Если выключено, то активности типа "блок" не будут отправлены.
regexpErrorDescription: 'Произошла ошибка в регулярном выражении на строке {line}
ваших {tab} заглушенных слов:'
reporter: Подавший жалобу

View file

@ -4,7 +4,6 @@ import config from '@/config/index.js';
import { UserProfiles } from '@/models/index.js';
import { extractMentions } from '@/misc/extract-mentions.js';
import { intersperse } from '@/prelude/array.js';
import { toPunyNullable } from '@/misc/convert-host.js';
// Transforms MFM to HTML, given the MFM text and a list of user IDs that are
// mentioned in the text. If the list of mentions is not given, all mentions
@ -15,19 +14,6 @@ export async function toHtml(mfmText: string, mentions?: string[]): Promise<stri
return null;
}
let mentionedUsers = [];
const ids = mentions ?? extractMentions(nodes);
if (ids.length > 0) {
mentionedUsers = await UserProfiles.createQueryBuilder('user_profile')
.leftJoin('user_profile.user', 'user')
.select('user.usernameLower', 'username')
.addSelect('user.host', 'host')
// links should preferably use user friendly urls, only fall back to AP ids
.addSelect('COALESCE(user_profile.url, user.uri)', 'url')
.where('"userId" IN (:...ids)', { ids })
.getRawMany();
}
const doc = new JSDOM('').window.document;
const handlers: { [K in mfm.MfmNode['type']]: (node: mfm.NodeType<K>) => Promise<Node> } = {
@ -117,28 +103,30 @@ export async function toHtml(mfmText: string, mentions?: string[]): Promise<stri
},
async mention(node): Promise<HTMLElement | Text> {
let { username, host, acct } = node.props;
// normalize username and host for searching the user
username = username.toLowerCase();
host = toPunyNullable(host);
// Discard host if it is the local host. Otherwise mentions of local users where the
// hostname is not omitted are not handled correctly.
if (host == config.hostname) {
host = null;
}
const userInfo = mentionedUsers.find(user => user.username === username && user.host === host);
if (userInfo != null) {
// Mastodon microformat: span.h-card > a.u-url.mention
const a = doc.createElement('a');
// The fallback will only be used for local users, so the host part can be discarded.
a.href = userInfo.url ?? `${config.url}/@${username}`;
a.className = 'u-url mention';
a.textContent = acct;
const { username, host, acct } = node.props;
const ids = mentions ?? extractMentions(nodes);
if (ids.length > 0) {
const mentionedUsers = await UserProfiles.createQueryBuilder('user_profile')
.leftJoin('user_profile.user', 'user')
.select('user.username', 'username')
.addSelect('user.host', 'host')
// links should preferably use user friendly urls, only fall back to AP ids
.addSelect('COALESCE(user_profile.url, user.uri)', 'url')
.where('"userId" IN (:...ids)', { ids })
.getRawMany();
const userInfo = mentionedUsers.find(user => user.username === username && user.host === host);
if (userInfo != null) {
// Mastodon microformat: span.h-card > a.u-url.mention
const a = doc.createElement('a');
a.href = userInfo.url ?? `${config.url}/${acct}`;
a.className = 'u-url mention';
a.textContent = acct;
const card = doc.createElement('span');
card.className = 'h-card';
card.appendChild(a);
return card;
const card = doc.createElement('span');
card.className = 'h-card';
card.appendChild(a);
return card;
}
}
// this user does not actually exist
return doc.createTextNode(acct);

View file

@ -7,7 +7,6 @@ import { Webhook, webhookEventTypes } from '@/models/entities/webhook.js';
import { IActivity } from '@/remote/activitypub/type.js';
import { envOption } from '@/env.js';
import { MINUTE } from '@/const.js';
import { DbResolver } from '@/remote/activitypub/db-resolver.js';
import processDeliver from './processors/deliver.js';
import processInbox from './processors/inbox.js';
@ -84,47 +83,24 @@ webhookDeliverQueue
.on('error', (job: any, err: Error) => webhookLogger.error(`error ${err}`, { job, e: renderError(err) }))
.on('stalled', (job) => webhookLogger.warn(`stalled ${getJobInfo(job)} to=${job.data.to}`));
export async function deliver(content: IActivity|IActivity[], to: string | null) {
export function deliver(content: unknown, to: string | null) {
if (content == null) return null;
if (to == null) return null;
// group activities by actor
const contentArray = Array.isArray(content) ? content : [content];
let byActor = contentArray.reduce((acc, activity) => {
if (activity.actor == null) throw new Error("Cannot deliver activity without actor.");
if (!(activity.actor in acc)) {
acc[activity.actor] = [];
}
acc[activity.actor].push(activity);
return acc;
}, []);
const data = {
content,
to,
};
// add groups to deliver queue
const dbResolver = new DbResolver();
for (const actor in byActor) {
// extract user from the Activity
const user = await dbResolver.getUserFromApId(actor);
if (!user) throw new Error("Actor not found, cannot deliver.");
if (user.host != null) throw new Error("Cannot deliver for remote actor.");
// add item to deliver queue
const data = {
user: {
id: user.id,
},
content: byActor[actor],
to,
};
deliverQueue.add(data, {
attempts: config.deliverJobMaxAttempts,
timeout: MINUTE,
backoff: {
type: 'apBackoff',
},
removeOnComplete: true,
removeOnFail: true,
});
}
return deliverQueue.add(data, {
attempts: config.deliverJobMaxAttempts,
timeout: MINUTE,
backoff: {
type: 'apBackoff',
},
removeOnComplete: true,
removeOnFail: true,
});
}
export function inbox(activity: IActivity, signature: httpSignature.IParsedSignature) {

View file

@ -9,6 +9,7 @@ import { toPuny } from '@/misc/convert-host.js';
import { StatusError } from '@/misc/fetch.js';
import { shouldSkipInstance } from '@/misc/skipped-instances.js';
import { DeliverJobData } from '@/queue/types.js';
import { DbResolver } from '@/remote/activitypub/db-resolver.js';
const logger = new Logger('deliver');
@ -18,13 +19,20 @@ export default async (job: Bull.Job<DeliverJobData>) => {
if (await shouldSkipInstance(puny)) return 'skip';
// get user/actor for signing
const userUri = job.data.content.actor;
if (userUri == null) return 'error: missing actor';
const user = await new DbResolver().getUserFromApId(userUri);
if (user == null) return 'error: actor not found';
if (user.host != null) return 'error: actor not local';
try {
if (Array.isArray(job.data.content)) {
await Promise.all(
job.data.content.map(x => request(job.data.user, job.data.to, x))
job.data.content.map(x => request(user, job.data.to, x))
);
} else {
await request(job.data.user, job.data.to, job.data.content);
await request(user, job.data.to, job.data.content);
}
// Update stats

View file

@ -6,9 +6,7 @@ import { Webhook } from '@/models/entities/webhook.js';
import { IActivity } from '@/remote/activitypub/type.js';
export type DeliverJobData = {
/** Actor */
user: ThinUser;
/** Activity */
/** Activity, containing the actor URI */
content: IActivity;
/** inbox URL to deliver */
to: string;

View file

@ -156,7 +156,7 @@ export class DeliverManager {
// skip instances as indicated
if (instancesToSkip.includes(new URL(inbox).host)) continue;
await deliver(this.activity, inbox);
deliver(this.activity, inbox);
}
}
}

View file

@ -29,7 +29,7 @@ export default define(meta, paramDef, async (ps, me) => {
const actor = await getInstanceActor();
const targetUser = await Users.findOneByOrFail({ id: report.targetUserId });
await deliver(renderActivity(renderFlag(actor, report)), targetUser.inbox);
deliver(renderActivity(renderFlag(actor, report)), targetUser.inbox);
}
await AbuseUserReports.update(report.id, {

View file

@ -133,7 +133,7 @@ export default define(meta, paramDef, async (ps, user) => {
if (note.userHost != null) {
const pollOwner = await Users.findOneByOrFail({ id: note.userId }) as IRemoteUser;
await deliver(renderActivity(await renderVote(user, vote, note, poll, pollOwner)), pollOwner.inbox);
deliver(renderActivity(await renderVote(user, vote, note, poll, pollOwner)), pollOwner.inbox);
}
// リモートフォロワーにUpdate配信

View file

@ -29,6 +29,6 @@ export default async function(blocker: CacheableUser, blockee: CacheableUser) {
// deliver if remote bloking
if (Users.isLocalUser(blocker) && Users.isRemoteUser(blockee)) {
const content = renderActivity(renderUndo(renderBlock(blocking), blocker));
await deliver(content, blockee.inbox);
deliver(content, blockee.inbox);
}
}

View file

@ -27,7 +27,7 @@ export async function acceptFollowRequest(followee: User, follower: User): Promi
if (Users.isRemoteUser(follower) && Users.isLocalUser(followee)) {
const content = renderActivity(renderAccept(renderFollow(follower, followee, request.requestId!), followee));
await deliver(content, follower.inbox);
deliver(content, follower.inbox);
}
Users.pack(followee.id, followee, {

View file

@ -17,7 +17,7 @@ export async function cancelFollowRequest(followee: User, follower: User): Promi
const content = renderActivity(renderUndo(renderFollow(follower, followee), follower));
if (Users.isLocalUser(follower)) {
await deliver(content, followee.inbox);
deliver(content, followee.inbox);
}
}

View file

@ -64,6 +64,6 @@ export async function createFollowRequest(follower: User, followee: User, reques
if (Users.isLocalUser(follower) && Users.isRemoteUser(followee)) {
const content = renderActivity(renderFollow(follower, followee));
await deliver(content, followee.inbox);
deliver(content, followee.inbox);
}
}

View file

@ -97,7 +97,7 @@ export async function createMessage(user: { id: User['id']; host: User['host'];
const activity = renderActivity(renderCreate(await renderNote(note, false, true), note));
await deliver(activity, recipientUser.inbox);
deliver(activity, recipientUser.inbox);
}
return messageObj;
}

View file

@ -22,7 +22,7 @@ async function postDeleteMessage(message: MessagingMessage): Promise<void> {
if (Users.isLocalUser(user) && Users.isRemoteUser(recipient)) {
const activity = renderActivity(renderDelete(renderTombstone(`${config.url}/notes/${message.id}`), user));
await deliver(activity, recipient.inbox);
deliver(activity, recipient.inbox);
}
} else if (message.groupId) {
publishGroupMessagingStream(message.groupId, 'deleted', message.id);

View file

@ -37,7 +37,7 @@ export async function addRelay(inbox: string): Promise<Relay> {
const relayActor = await getRelayActor();
const activity = renderActivity(renderFollowRelay(relay, relayActor));
await deliver(activity, relay.inbox);
deliver(activity, relay.inbox);
return relay;
}
@ -53,7 +53,7 @@ export async function removeRelay(inbox: string): Promise<void> {
const relayActor = await getRelayActor();
const activity = renderActivity(renderUndo(renderFollowRelay(relay, relayActor), relayActor));
await deliver(activity, relay.inbox);
deliver(activity, relay.inbox);
await Relays.delete(relay.id);
}
@ -89,9 +89,9 @@ export async function deliverToRelays(user: { id: User['id']; host: null; }, act
const signed = await attachLdSignature(copy, user);
await Promise.all(relays.map(relay =>
deliver(signed, relay.inbox)
));
for (const relay of relays) {
deliver(signed, relay.inbox);
}
}
export async function deliverMultipleToRelays(user: User, activities: any[]): Promise<void> {
@ -107,7 +107,7 @@ export async function deliverMultipleToRelays(user: User, activities: any[]): Pr
return attachLdSignature(copy, user);
}));
await Promise.all(relays.map(relay =>
deliver(content, relay.inbox)
));
for (const relay of relays) {
deliver(content, relay.inbox);
}
}

View file

@ -32,7 +32,7 @@ export async function doPostUnsuspend(user: User): Promise<void> {
}
for (const inbox of queue) {
await deliver(content, inbox);
deliver(content, inbox);
}
}
}