Compare commits

...

42 Commits

Author SHA1 Message Date
syuilo
f748c9144c 2023.9.0-beta.11 2023-09-22 16:59:37 +09:00
anatawa12
526b3ae0e4 feat: ユーザを除外できるアンテナ (#11277)
* feat: ユーザを除外できるアンテナ

* feat(backend/api): ユーザを除外できるアンテナの作成・更新

* feat(frontend): ユーザを除外できるアンテナの作成・更新

* docs(changelog): add アンテナで一部のユーザを除外したすべてのノートから受信できるようになりました

* fix: d.ts生成時にexport defaultを生成するように

* fix CHANGELOG.md

---------

Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
2023-09-22 16:52:43 +09:00
syuilo
90a5511a54 Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-09-22 16:47:45 +09:00
syuilo
032b6c6afb update deps 2023-09-22 16:47:42 +09:00
syuilo
ee83b9542e New Crowdin updates (#11856)
* New translations ja-jp.yml (German)

* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (French)

* New translations ja-jp.yml (Italian)

* New translations ja-jp.yml (Portuguese)

* New translations ja-jp.yml (Portuguese)

* New translations ja-jp.yml (English)

* New translations ja-jp.yml (Vietnamese)

* New translations ja-jp.yml (Vietnamese)

* New translations ja-jp.yml (German)

* New translations ja-jp.yml (English)

* New translations ja-jp.yml (German)

* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (English)

* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (Italian)

* New translations ja-jp.yml (German)

* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (English)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (Italian)

* New translations ja-jp.yml (Italian)

* New translations ja-jp.yml (German)

* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (Italian)

* New translations ja-jp.yml (Spanish)

* New translations ja-jp.yml (Czech)

* New translations ja-jp.yml (Korean)

* New translations ja-jp.yml (Russian)

* New translations ja-jp.yml (Swedish)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (English)

* New translations ja-jp.yml (Vietnamese)

* New translations ja-jp.yml (Indonesian)

* New translations ja-jp.yml (Thai)

* New translations ja-jp.yml (Japanese, Kansai)
2023-09-22 16:46:08 +09:00
typeling1578
3bbc2e55b1 fix(backend): mostr.pub, Mitraのユーザーをフォローできない問題を修正 (#11791)
* fix(backend): mostr.pub, Mitraのユーザーをフォローできない問題を修正

* Revert "fix(backend): mostr.pub, Mitraのユーザーをフォローできない問題を修正"

This reverts commit 9685715e64.

* fix ApResolverService

* Update CHANGELOG.md

* fix test

---------

Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
2023-09-22 16:43:01 +09:00
かっこかり
7dc9fe4e24 feat(frontend): センシティブなメディアを目立たせる設定を追加 (#11851)
* (add) highlight sensitive image

* Update Changelog

* (change) 設定の位置

* (add) apply mediaHighlight to video

* (change) image -> media

* Update CHANGELOG

* やっぱもうちょっと太い方がいい

* (fix) style

* Update ja-JP.yml

---------

Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
2023-09-22 16:03:10 +09:00
syuilo
c836157edb enhance: 二要素認証設定時のセキュリティを強化 (#11863)
* enhance: 二要素認証設定時のセキュリティを強化

パスワード入力が必要な操作を行う際、二要素認証が有効であれば確認コードの入力も必要にする

* Update CoreModule.ts

* Update 2fa.ts

* wip

* wip

* Update 2fa.ts

* tweak
2023-09-22 14:12:33 +09:00
syuilo
eca8c7a52f tweak ui 2023-09-22 10:01:34 +09:00
syuilo
03b5acf17f fix test 2023-09-21 19:39:42 +09:00
syuilo
e3f151e230 feat: 指定したユーザーの投稿通知
Resolve #11499
2023-09-21 18:48:15 +09:00
syuilo
f195fa4ab9 2023.9.0-beta.10 2023-09-21 15:24:50 +09:00
syuilo
51c3ef5561 update deps 2023-09-21 15:24:47 +09:00
syuilo
b654446f93 enhance(frontend): tweak ui 2023-09-21 15:14:08 +09:00
syuilo
e41619775f feat: プロフィールでのリンク検証
Resolve #11099
2023-09-21 11:58:51 +09:00
syuilo
1250309a69 🎨 2023-09-21 10:29:40 +09:00
syuilo
6459eadcf1 update deps 2023-09-21 10:25:44 +09:00
syuilo
1dddc68709 Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-09-20 16:44:53 +09:00
syuilo
f9916d216a 2023.9.0-beta.9 2023-09-20 16:44:44 +09:00
syuilo
9abda93811 New Crowdin updates (#11840)
* New translations ja-JP.yml (Chinese Simplified)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Japanese, Kansai)

* New translations ja-JP.yml (Thai)

* New translations ja-jp.yml (German)

* New translations ja-jp.yml (Vietnamese)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (English)

* New translations ja-jp.yml (German)

* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (Italian)

* New translations ja-jp.yml (Italian)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (Vietnamese)
2023-09-20 16:44:26 +09:00
syuilo
8e2d47b2e8 refactor 2023-09-20 16:44:12 +09:00
syuilo
b9c6992aac update deps (#11849)
* update deps

* wip

* wip
2023-09-20 16:43:45 +09:00
typeling1578
cb026a7512 Update Dockerfile (#11848) 2023-09-20 13:28:42 +09:00
syuilo
fa13b815ef fix: provide NoSuchNoteError error 2023-09-20 11:43:33 +09:00
syuilo
5d65e34078 fix import 2023-09-20 11:40:17 +09:00
syuilo
0183d24786 Update ClipService.ts 2023-09-20 11:36:39 +09:00
syuilo
053da10e94 refactor(backend): update directory structure for models 2023-09-20 11:33:36 +09:00
syuilo
c3db55b5b6 fix 2023-09-20 11:29:10 +09:00
syuilo
bb460a1785 feat(frontend): スリープ無効化機能
Resolve #11853
2023-09-20 10:02:39 +09:00
syuilo
bb0b2df37e refactor(backend): extract clip-related logics to ClipService 2023-09-20 09:33:52 +09:00
syuilo
934e4be658 fix(frontend): 環境によってはMisskey Webが開けない問題を修正
Fix #11846
2023-09-19 17:08:55 +09:00
syuilo
09c00d0a1b Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-09-19 17:06:58 +09:00
syuilo
e98fbfeec1 cjs 2023-09-19 17:06:56 +09:00
FineArchs
578b0ebe0c Scratchpadに非同期のエラーを処理する機能を追加 (#11850)
* opts.callをtopCallに置換

* AiScriptのエラーコールバックをscratchpadに導入

* lint

* Update CHANGELOG.md
2023-09-19 16:53:43 +09:00
syuilo
b0f6c44f36 refactor(frontend): use ESM 2023-09-19 16:37:43 +09:00
syuilo
299c9c4118 feat(frontend): 任意のユーザーリストをタイムラインページにピン留めできるように 2023-09-19 10:58:42 +09:00
syuilo
bec338aa00 Update .eslintrc.js 2023-09-19 09:44:05 +09:00
syuilo
5c48878dc5 enhance(dev): 関数呼び出しの前にスペースを入れることを許可しない 2023-09-19 09:36:07 +09:00
FineArchs
44985ae858 feat: Mk:apiが失敗時エラー型の値を返すように (#2) (#11843)
* Mk:apiが失敗時エラー型の値を返すように (#2)

* Update CHANGELOG.md
2023-09-18 14:23:33 +09:00
syuilo
aa80cfdb81 Update .eslintrc.js 2023-09-18 13:26:43 +09:00
syuilo
25ae4bca9c tab 2023-09-18 13:25:49 +09:00
syuilo
350ebbadba fix(frontend): prevent layout-shift of reactions viewer
Fix #11842
2023-09-18 11:42:26 +09:00
749 changed files with 4817 additions and 4002 deletions

View File

@@ -15,47 +15,59 @@
## 2023.9.0 (unreleased)
### General
- OAuth 2.0のサポート
- お知らせ機能の強化
- Feat: OAuth 2.0のサポート
- Feat: お知らせ機能の強化
- ユーザー個別のお知らせを作成可能に
- お知らせのバナー表示やダイアログ表示が可能に
- お知らせのアイコンを設定可能に
- チャンネルをセンシティブ指定できるようになりました
- Feat: チャンネルをセンシティブ指定できるようになりました
- センシティブチャンネルのNoteのReNoteはデフォルトでHome TLに流れるようになりました
- センシティブチャンネルのノートはユーザープロフィールに表示されません
- 二要素認証のバックアップコードが生成されるようになりました ref. https://github.com/MisskeyIO/misskey/pull/121
- 二要素認証でパスキーをサポートするようになりました
- 通知をテストできるようになりました
- PWAのアイコンが設定できるようになりました
- manifest.jsonをオーバーライド可能に
- 依存関係の更新
- ローカリゼーションの更新
- Feat: 二要素認証のバックアップコードが生成されるようになりました
- ref. https://github.com/MisskeyIO/misskey/pull/121
- Feat: 二要素認証でパスキーをサポートするようになりました
- Feat: 指定したユーザーが投稿したときに通知できるようになりました
- Feat: プロフィールでのリンク検証
- Feat: 通知をテストできるようになりました
- Feat: PWAのアイコンが設定できるようになりました
- Enhance: アンテナの受信ソースに指定したユーザを除外するものを追加
- Enhance: 二要素認証設定時のセキュリティを強化
- パスワード入力が必要な操作を行う際、二要素認証が有効であれば確認コードの入力も必要になりました
- Enhance: manifest.jsonをオーバーライド可能に
- Enhance: 依存関係の更新
- Enhance: ローカリゼーションの更新
### Client
- ノート詳細ページを改修
- 読み込み時のパフォーマンスが向上しました
- リノート一覧、リアクション一覧がタブとして追加されました
- ノートのメニューからは当該項目は消えました
- プロフィールにその人が作ったPlayの一覧出せるように
- メニューのスイッチの動作を改善
- 絵文字ピッカーの検索の表示件数を100件に増加
- 投稿フォームのプレビューの表示状態を記憶するように
- AiScriptからMisskeyサーバーAPIを呼び出す際の制限を撤廃
- Playで直接投稿フォームを埋め込めるように(`Ui:C:postForm`)
- Feat: 任意のユーザーリストをタイムラインページにピン留めできるように
- 設定->クライアント設定->全般 から設定可能です
- Feat: Playで直接投稿フォームを埋め込めるように(`Ui:C:postForm`)
- Feat: クライアントを起動している間、デバイスの画面が自動でオフになるのを防ぐオプションを追加
- Feat: 新しい実績を追加
- Enhance: ノート詳細ページでリノート一覧、リアクション一覧タブを追加
- ノートのメニューからは当該項目は消えました
- Enhance: センシティブなメディアを目立たせる設定を追加
- Enhance: プロフィールにその人が作ったPlayの一覧出せるように
- Enhance: メニューのスイッチの動作を改善
- Enhance: 絵文字ピッカーの検索の表示件数を100件に増加
- Enhance: 投稿フォームのプレビューの表示状態を記憶するように
- Enhance: ユーザーメニューでスイッチでユーザーリストに追加・削除できるように
- Enhance: 自分が押したリアクションのデザインを改善
- Enhance: ノート検索にローカルのみ検索可能なオプションの追加
- Enhance: AiScriptで`LOCALE`として現在の設定言語を取得できるように
- Enhance: Renote自体を通報できるように
- Enhance: データセーバーモードの強化
- Enhance: Renoteを管理者権限で削除可能に
- `$[rainbow ]`記法が、動きのあるMFMが無効になっていても使用できるようになりました
- Playの操作を行うAPI TokenをAPIコンソールから発行できるように
- リアクションの表示サイズをより大きくできるように
- AiScriptを0.16.0に更新
- タイムラインでリスト/アンテナ選択時のパフォーマンスを改善
- 「Moderation note」、「Add moderation note」をローカライズできるように
- 新しい実績を追加
- Enhance: `$[rainbow ]`記法が、動きのあるMFMが無効になっていても使用できるようになりました
- Enhance: Playの操作を行うAPI TokenをAPIコンソールから発行できるように
- Enhance: リアクションの表示サイズをより大きくできるように
- Enhance: AiScriptを0.16.0に更新
- Enhance: AiScriptからMisskeyサーバーAPIを呼び出す際の制限を撤廃
- Enhance: AiScriptで`LOCALE`として現在の設定言語を取得できるように
- Enhance: Mk:apiが失敗した時にエラー型の値AiScript 0.16.0で追加)を返すように
- Enhance: ScratchpadでAsync:系関数やボタンのコールバックなどのエラーにもダイアログを出すように試験的なためPlayなどには未実装
- Enhance: ノート詳細ページ読み込み時のパフォーマンスが向上しました
- Enhance: タイムラインでリスト/アンテナ選択時のパフォーマンスを改善
- Enhance: 「Moderation note」、「Add moderation note」をローカライズできるように
- Enhance: 細かなデザインの調整
- Fix: サーバー情報画面(`/instance-info/{domain}`)でブロックができないのを修正
- Fix: 未読のお知らせの「わかった」をクリック・タップしてもその場で「わかった」が消えない問題を修正
- Fix: iOSで画面を回転させるとテキストサイズが変わる問題を修正
@@ -63,22 +75,24 @@
- Fix: タイムラインを下にスクロールしてノート画面に移動して再び戻ったら以前のスクロール位置を失う問題を修正
- Fix: Misskeyプラグインをインストールする際のAiScriptバージョンのチェックが0.14.0以降に対応していない問題を修正
- Fix: 他のサーバーのユーザーへ「メッセージを送信」した時の初期テキストのメンションが間違っている問題を修正
- Fix: 環境によってはMisskey Webが開けない問題を修正
### Server
- cacheRemoteFilesの初期値はfalseになりました
- ファイルアップロード時等にファイル名の拡張子を修正する関数(correctFilename)の挙動を改善
- Webhookのペイロードにサーバーのurlが含まれるようになりました
- Webhook設定でsecretを空に出来るように
- 使われていないアンテナの自動停止を設定可能に
- nodeinfo 2.1対応
- 自分へのメンション一覧を取得する際のパフォーマンスを向上
- Docker環境でjemallocを使用することでメモリ使用量を削減
- Change: cacheRemoteFilesの初期値はfalseになりました
- Enhance: ファイルアップロード時等にファイル名の拡張子を修正する関数(correctFilename)の挙動を改善
- Enhance: Webhookのペイロードにサーバーのurlが含まれるようになりました
- Enhance: Webhook設定でsecretを空に出来るように
- Enhance: 使われていないアンテナの自動停止を設定可能に
- Enhance: nodeinfo 2.1対応
- Enhance: 自分へのメンション一覧を取得する際のパフォーマンスを向上
- Enhance: Docker環境でjemallocを使用することでメモリ使用量を削減
- Fix: MK_ONLY_SERVERオプションを指定した際にクラッシュする問題を修正
- Fix: ノート検索 `notes/search` にてhostを指定した際に検索結果に反映されるように
- Fix: 一部のfeatured noteを照会できない問題を修正
- Fix: muteがapiからのuser list timeline取得で機能しない問題を修正
- Fix: ジョブキュー管理画面の認証を回避できる問題を修正
- Fix: 一部のサーバー内部エラーがスタックトレースを返さないように修正
- Fix: 一部のリモートユーザーをフォローすることができない問題を修正
## 13.14.2

View File

@@ -63,6 +63,7 @@ ARG GID="991"
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ffmpeg tini curl libjemalloc-dev libjemalloc2 \
&& ln -s /usr/lib/$(uname -m)-linux-gnu/libjemalloc.so.2 /usr/local/lib/libjemalloc.so \
&& corepack enable \
&& groupadd -g "${GID}" misskey \
&& useradd -l -u "${UID}" -g "${GID}" -m -d /misskey misskey \
@@ -81,7 +82,7 @@ COPY --chown=misskey:misskey --from=native-builder /misskey/packages/backend/bui
COPY --chown=misskey:misskey --from=native-builder /misskey/fluent-emojis /misskey/fluent-emojis
COPY --chown=misskey:misskey . ./
ENV LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2
ENV LD_PRELOAD=/usr/local/lib/libjemalloc.so
ENV NODE_ENV=production
HEALTHCHECK --interval=5s --retries=20 CMD ["/bin/bash", "/misskey/healthcheck.sh"]
ENTRYPOINT ["/usr/bin/tini", "--"]

View File

@@ -1679,7 +1679,6 @@ _timelineTutorial:
_2fa:
alreadyRegistered: "Již jste zaregistrovali dvoufaktorové ověřovací zařízení."
registerTOTP: "Registrovat aplikaci autentizátoru"
passwordToTOTP: "Zadejte své heslo"
step1: "Nejprve si do zařízení nainstalujte aplikaci pro ověřování (například {a} nebo {b})."
step2: "Poté naskenujte QR kód zobrazený na této obrazovce."
step2Click: "Kliknutím na tento QR kód můžete zaregistrovat 2FA do bezpečnostního klíče nebo aplikace autentizace telefonu."

View File

@@ -1108,7 +1108,14 @@ pastAnnouncements: "Alte Ankündigungen"
youHaveUnreadAnnouncements: "Es gibt neue Ankündigungen."
useSecurityKey: "Folge bitten den Anweisungen deines Browsers bzw. Gerätes und verwende deinen Hardware-Sicherheitsschlüssel oder Passkey."
replies: "Antworten"
renotes: "Renote"
renotes: "Renotes"
loadReplies: "Antworten anzeigen"
loadConversation: "Unterhaltung anzeigen"
pinnedList: "Angeheftete Liste"
keepScreenOn: "Bildschirm angeschaltet lassen"
verifiedLink: "Link-Besitz wurde verifiziert"
notifyNotes: "Über neue Notizen benachrichtigen"
unnotifyNotes: "Nicht über neue Notizen benachrichtigen"
_announcement:
forExistingUsers: "Nur für existierende Nutzer"
forExistingUsersDescription: "Ist diese Option aktiviert, wird diese Ankündigung nur Nutzern angezeigt, die zum Zeitpunkt der Ankündigung bereits registriert sind. Ist sie deaktiviert, wird sie auch Nutzern, die sich nach dessen Veröffentlichung registrieren, angezeigt."
@@ -1709,7 +1716,6 @@ _timelineTutorial:
_2fa:
alreadyRegistered: "Du hast bereits ein Gerät für Zwei-Faktor-Authentifizierung registriert."
registerTOTP: "Authentifizierungs-App registrieren"
passwordToTOTP: "Bitte Passwort eingeben"
step1: "Installiere zuerst eine Authentifizierungsapp (z.B. {a} oder {b}) auf deinem Gerät."
step2: "Dann, scanne den angezeigten QR-Code mit deinem Gerät."
step2Click: "Durch Klicken dieses QR-Codes kannst du Verifikation mit deinem Security-Token oder einer App registrieren."
@@ -1887,6 +1893,7 @@ _profile:
metadataContent: "Inhalt"
changeAvatar: "Profilbild ändern"
changeBanner: "Banner ändern"
verifiedLinkDescription: "Gibst du hier eine URL ein, die einen Link zu deinem Profile enthält, wird neben diesem Feld ein Icon zur Besitzbestätigung angezeigt."
_exportOrImport:
allNotes: "Alle Notizen"
favoritedNotes: "Als Favorit markierte Notizen"
@@ -2005,6 +2012,7 @@ _notification:
youReceivedFollowRequest: "Du hast eine Follow-Anfrage erhalten"
yourFollowRequestAccepted: "Deine Follow-Anfrage wurde akzeptiert"
pollEnded: "Umfrageergebnisse sind verfügbar"
newNote: "Neue Notiz"
unreadAntennaNote: "Antenne {name}"
emptyPushNotificationMessage: "Push-Benachrichtigungen wurden aktualisiert"
achievementEarned: "Errungenschaft freigeschaltet"

View File

@@ -1108,7 +1108,14 @@ pastAnnouncements: "Past announcements"
youHaveUnreadAnnouncements: "There are unread announcements."
useSecurityKey: "Please follow your browser's or device's instructions to use your security- or passkey."
replies: "Reply"
renotes: "Renote"
renotes: "Renotes"
loadReplies: "Show replies"
loadConversation: "Show conversation"
pinnedList: "Pinned list"
keepScreenOn: "Keep screen on"
verifiedLink: "Link ownership has been verified"
notifyNotes: "Notify about new notes"
unnotifyNotes: "Stop notifying about new notes"
_announcement:
forExistingUsers: "Existing users only"
forExistingUsersDescription: "This announcement will only be shown to users existing at the point of publishment if enabled. If disabled, those newly signing up after it has been posted will also see it."
@@ -1709,7 +1716,6 @@ _timelineTutorial:
_2fa:
alreadyRegistered: "You have already registered a 2-factor authentication device."
registerTOTP: "Register authenticator app"
passwordToTOTP: "Enter your password"
step1: "First, install an authentication app (such as {a} or {b}) on your device."
step2: "Then, scan the QR code displayed on this screen."
step2Click: "Clicking on this QR code will allow you to register 2FA to your security key or phone authenticator app."
@@ -1887,6 +1893,7 @@ _profile:
metadataContent: "Content"
changeAvatar: "Change avatar"
changeBanner: "Change banner"
verifiedLinkDescription: "By entering an URL that contains a link to your profile here, an ownership verification icon can be displayed next to the field."
_exportOrImport:
allNotes: "All notes"
favoritedNotes: "Favorite notes"
@@ -2005,6 +2012,7 @@ _notification:
youReceivedFollowRequest: "You've received a follow request"
yourFollowRequestAccepted: "Your follow request was accepted"
pollEnded: "Poll results have become available"
newNote: "New note"
unreadAntennaNote: "Antenna {name}"
emptyPushNotificationMessage: "Push notifications have been updated"
achievementEarned: "Achievement unlocked"

View File

@@ -1705,7 +1705,6 @@ _timelineTutorial:
_2fa:
alreadyRegistered: "Ya has completado la configuración."
registerTOTP: "Registrar aplicación autenticadora"
passwordToTOTP: "Ingresa tu contraseña"
step1: "Primero, instale en su dispositivo la aplicación de autenticación {a} o {b} u otra."
step2: "Luego, escanee con la aplicación el código QR mostrado en pantalla."
step2Click: "Clicking on this QR code will allow you to register 2FA to your security key or phone authenticator app.\nTocar este código QR te permitirá registrar la autenticación 2FA a tu llave de seguridad o aplicación autenticadora."

View File

@@ -480,6 +480,7 @@ createAccount: "Créer un compte"
existingAccount: "Compte existant"
regenerate: "Générer à nouveau"
fontSize: "Taille de la police"
limitTo: "Limiter à {x}"
noFollowRequests: "Vous navez aucune demande dabonnement en attente"
openImageInNewTab: "Ouvrir les images dans un nouvel onglet"
dashboard: "Tableau de bord"

View File

@@ -1683,7 +1683,6 @@ _timelineTutorial:
_2fa:
alreadyRegistered: "Kamu telah mendaftarkan perangkat otentikasi dua faktor."
registerTOTP: "Daftarkan aplikasi autentikator"
passwordToTOTP: "Masukkan kata sandimu"
step1: "Pertama, pasang aplikasi otentikasi (seperti {a} atau {b}) di perangkat kamu."
step2: "Lalu, pindai kode QR yang ada di layar."
step2Click: "Mengeklik kode QR ini akan membolehkanmu untuk mendaftarkan 2FA ke security-key atau aplikasi autentikator ponsel."

12
locales/index.d.ts vendored
View File

@@ -713,6 +713,7 @@ export interface Locale {
"alwaysMarkSensitive": string;
"loadRawImages": string;
"disableShowingAnimatedImages": string;
"highlightSensitiveMedia": string;
"verificationEmailSent": string;
"notSet": string;
"emailVerified": string;
@@ -1114,6 +1115,13 @@ export interface Locale {
"renotes": string;
"loadReplies": string;
"loadConversation": string;
"pinnedList": string;
"keepScreenOn": string;
"verifiedLink": string;
"notifyNotes": string;
"unnotifyNotes": string;
"authentication": string;
"authenticationRequiredToContinue": string;
"_announcement": {
"forExistingUsers": string;
"forExistingUsersDescription": string;
@@ -1828,7 +1836,6 @@ export interface Locale {
"_2fa": {
"alreadyRegistered": string;
"registerTOTP": string;
"passwordToTOTP": string;
"step1": string;
"step2": string;
"step2Click": string;
@@ -1910,6 +1917,7 @@ export interface Locale {
"homeTimeline": string;
"users": string;
"userList": string;
"userBlacklist": string;
};
"_weekday": {
"sunday": string;
@@ -2018,6 +2026,7 @@ export interface Locale {
"metadataContent": string;
"changeAvatar": string;
"changeBanner": string;
"verifiedLinkDescription": string;
};
"_exportOrImport": {
"allNotes": string;
@@ -2146,6 +2155,7 @@ export interface Locale {
"youReceivedFollowRequest": string;
"yourFollowRequestAccepted": string;
"pollEnded": string;
"newNote": string;
"unreadAntennaNote": string;
"emptyPushNotificationMessage": string;
"achievementEarned": string;

View File

@@ -134,7 +134,7 @@ renoteMute: "Silenzia i Rinota"
renoteUnmute: "Non silenziare i Rinota"
block: "Blocca"
unblock: "Sblocca"
suspend: "Sospendi"
suspend: "Sospensione"
unsuspend: "Revoca la sospensione"
blockConfirm: "Vuoi davvero bloccare il profilo?"
unblockConfirm: "Vuoi davvero sbloccare il profilo?"
@@ -180,7 +180,7 @@ youHaveNoLists: "Non hai ancora creato nessuna lista"
followConfirm: "Vuoi seguire {name}?"
proxyAccount: "Profilo proxy"
proxyAccountDescription: "Un profilo proxy funziona come follower per i profili remoti, sotto certe condizioni. Ad esempio, quando un profilo locale ne inserisce uno remoto in una lista (senza seguirlo), se nessun altro segue quel profilo remoto, le attività non possono essere distribuite. Dunque, il profilo proxy le seguirà per tutti."
host: "Server remoto"
host: "Host"
selectUser: "Seleziona profilo"
recipient: "Destinatario"
annotation: "Annotazione preventiva"
@@ -287,7 +287,7 @@ images: "Immagini"
image: "Immagini"
birthday: "Compleanno"
yearsOld: "{age} anni"
registeredDate: "Iscrizione a.."
registeredDate: "Data iscrizione"
location: "Posizione"
theme: "Tema"
themeForLightMode: "Tema da utilizzare per il modo chiaro"
@@ -496,7 +496,7 @@ noFollowRequests: "Non hai alcuna richiesta di follow"
openImageInNewTab: "Apri le immagini in un nuovo tab"
dashboard: "Pannello di controllo"
local: "Locale"
remote: "Remoto"
remote: "Remota"
total: "Totale"
weekOverWeekChanges: "Settimanale"
dayOverDayChanges: "Giornaliero"
@@ -551,8 +551,8 @@ installedDate: "Data installazione"
lastUsedDate: "Data di ultimo uso"
state: "Stato"
sort: "Ordina per"
ascendingOrder: "Ascendente"
descendingOrder: "Discendente"
ascendingOrder: "Aumenta"
descendingOrder: "Diminuisce"
scratchpad: "ScratchPad"
scratchpadDescription: "Lo Scratchpad offre un ambiente per esperimenti di AiScript. È possibile scrivere, eseguire e confermare i risultati dell'interazione del codice con Misskey."
output: "Uscita"
@@ -621,7 +621,7 @@ emailConfigInfo: "Utilizzato per verificare il tuo indirizzo di posta elettronic
email: "Email"
emailAddress: "Indirizzo di posta elettronica"
smtpConfig: "Impostazioni del server SMTP"
smtpHost: "Server remoto"
smtpHost: "Host SMTP"
smtpPort: "Porta"
smtpUser: "Nome utente"
smtpPass: "Password"
@@ -1109,6 +1109,13 @@ youHaveUnreadAnnouncements: "Ci sono Annunci non letti"
useSecurityKey: "Per utilizzare la chiave di sicurezza o la passkey, segui le indicazioni del dispositivo"
replies: "Rispondi"
renotes: "Rinota"
loadReplies: "Leggi le risposte"
loadConversation: "Leggi la conversazione"
pinnedList: "Elenco in primo piano"
keepScreenOn: "Mantieni lo schermo acceso"
verifiedLink: "Abbiamo confermato la validità di questo collegamento"
notifyNotes: "Notifica nuove Note"
unnotifyNotes: "Interrompi le notifiche di nuove Note"
_announcement:
forExistingUsers: "Solo ai profili attuali"
forExistingUsersDescription: "L'annuncio sarà visibile solo ai profili esistenti in questo momento. Se disabilitato, sarà visibile anche ai profili che verranno creati dopo la pubblicazione di questo annuncio."
@@ -1137,6 +1144,11 @@ _serverRules:
description: "In Europa è necessario mostrare l'informativa sul trattamento dei dati personali, prima della registrazione al servizio."
_serverSettings:
iconUrl: "URL dell'icona"
appIconDescription: "Indicare l'icona da usare quando {host} viene salvata come App."
appIconUsageExample: "Ad esempio quando si aggiunge il segnalibro alla PWA (Progressive Web App), oppure alla schermata iniziale del dispositivo mobile "
appIconStyleRecommendation: "Poiché l'icona potrebbe essere ritagliata in un quadrato o in un cerchio, si raccomanda che abbia un margine colorato."
appIconResolutionMustBe: "La risoluzione minima è {resolution}"
manifestJsonOverride: "Sostituire il file manifest.json"
_accountMigration:
moveFrom: "Migra un altro profilo dentro a questo"
moveFromSub: "Crea un alias verso un altro profilo remoto"
@@ -1454,10 +1466,10 @@ _role:
_condition:
isLocal: "Profilo locale"
isRemote: "Profilo remoto"
createdLessThan: "Creato meno di"
createdMoreThan: "Creato più di"
followersLessThanOrEq: "Ha meno di N follower"
followersMoreThanOrEq: "Ha più di N follower"
createdLessThan: "Profilo creato da meno di N"
createdMoreThan: "Profilo creato da più di N"
followersLessThanOrEq: "Profilo con N follower o meno"
followersMoreThanOrEq: "Profilo con N follower o più"
followingLessThanOrEq: "Segue N profili o meno"
followingMoreThanOrEq: "Segue N profili o più"
notesLessThanOrEq: "Conteggio Note inferiore o uguale a"
@@ -1704,7 +1716,6 @@ _timelineTutorial:
_2fa:
alreadyRegistered: "La configurazione è stata già completata."
registerTOTP: "Registra un'app di autenticazione"
passwordToTOTP: "Inserire la password"
step1: "Innanzitutto, installare sul dispositivo un'applicazione di autenticazione come {a} o {b}."
step2: "Quindi, scansionare il codice QR visualizzato con l'app."
step2Click: "Cliccando sul codice QR, puoi registrarlo con l'app di autenticazione o il portachiavi installato sul tuo dispositivo."
@@ -1882,6 +1893,7 @@ _profile:
metadataContent: "Contenuto"
changeAvatar: "Modifica immagine profilo"
changeBanner: "Cambia intestazione"
verifiedLinkDescription: "Puoi verificare il tuo profilo mostrando una icona. Devi inserire la URL alla pagina che contiene un link al tuo profilo."
_exportOrImport:
allNotes: "Tutte le note"
favoritedNotes: "Note preferite"
@@ -2000,6 +2012,7 @@ _notification:
youReceivedFollowRequest: "Hai ricevuto una richiesta di follow"
yourFollowRequestAccepted: "La tua richiesta di follow è stata accettata"
pollEnded: "Risultati del sondaggio."
newNote: "Nuove Note"
unreadAntennaNote: "Antenna {name}"
emptyPushNotificationMessage: "Le notifiche push sono state aggiornate."
achievementEarned: "Obiettivo raggiunto"

View File

@@ -710,6 +710,7 @@ lockedAccountInfo: "フォローを承認制にしても、ノートの公開範
alwaysMarkSensitive: "デフォルトでメディアをセンシティブ設定にする"
loadRawImages: "添付画像のサムネイルをオリジナル画質にする"
disableShowingAnimatedImages: "アニメーション画像を再生しない"
highlightSensitiveMedia: "メディアがセンシティブであることを分かりやすく表示"
verificationEmailSent: "確認のメールを送信しました。メールに記載されたリンクにアクセスして、設定を完了してください。"
notSet: "未設定"
emailVerified: "メールアドレスが確認されました"
@@ -1111,6 +1112,13 @@ replies: "返信"
renotes: "リノート"
loadReplies: "返信を見る"
loadConversation: "会話を見る"
pinnedList: "ピン留めされたリスト"
keepScreenOn: "デバイスの画面を常にオンにする"
verifiedLink: "このリンク先の所有者であることが確認されました"
notifyNotes: "投稿を通知"
unnotifyNotes: "投稿の通知を解除"
authentication: "認証"
authenticationRequiredToContinue: "続けるには認証を行ってください"
_announcement:
forExistingUsers: "既存ユーザーのみ"
@@ -1745,7 +1753,6 @@ _timelineTutorial:
_2fa:
alreadyRegistered: "既に設定は完了しています。"
registerTOTP: "認証アプリの設定を開始"
passwordToTOTP: "パスワードを入力してください"
step1: "まず、{a}や{b}などの認証アプリをお使いのデバイスにインストールします。"
step2: "次に、表示されているQRコードをアプリでスキャンします。"
step2Click: "QRコードをクリックすると、お使いの端末にインストールされている認証アプリやキーリングに登録できます。"
@@ -1827,6 +1834,7 @@ _antennaSources:
homeTimeline: "フォローしているユーザーのノート"
users: "指定した一人または複数のユーザーのノート"
userList: "指定したリストのユーザーのノート"
userBlacklist: "指定した一人または複数のユーザーを除いた全てのノート"
_weekday:
sunday: "日曜日"
@@ -1933,6 +1941,7 @@ _profile:
metadataContent: "内容"
changeAvatar: "アイコン画像を変更"
changeBanner: "バナー画像を変更"
verifiedLinkDescription: "内容にURLを設定すると、リンク先のWebサイトに自分のプロフィールへのリンクが含まれている場合に所有者確認済みアイコンを表示させることができます。"
_exportOrImport:
allNotes: "全てのノート"
@@ -2060,6 +2069,7 @@ _notification:
youReceivedFollowRequest: "フォローリクエストが来ました"
yourFollowRequestAccepted: "フォローリクエストが承認されました"
pollEnded: "アンケートの結果が出ました"
newNote: "新しい投稿"
unreadAntennaNote: "アンテナ {name}"
emptyPushNotificationMessage: "プッシュ通知の更新をしました"
achievementEarned: "実績を獲得"

View File

@@ -1102,6 +1102,7 @@ forYou: "あんたへ"
currentAnnouncements: "現在のお知らせやで"
pastAnnouncements: "過去のお知らせやで"
youHaveUnreadAnnouncements: "あんたまだこのお知らせ読んどらんやろ。"
useSecurityKey: "ブラウザまたはデバイスの言う通りに、セキュリティキーまたはパスキーを使ってや。"
replies: "返事"
renotes: "Renote"
_announcement:
@@ -1696,7 +1697,6 @@ _timelineTutorial:
_2fa:
alreadyRegistered: "もう設定終わっとるわ。"
registerTOTP: "認証アプリの設定はじめる"
passwordToTOTP: "パスワードを入れてーや"
step1: "ほんなら、{a}や{b}とかの認証アプリを使っとるデバイスにインストールしてな。"
step2: "次に、ここにあるQRコードをアプリでスキャンしてな。"
step2Click: "QRコードをクリックすると、今使とる端末に入っとる認証アプリとかキーリングに登録できるで。"

View File

@@ -1699,7 +1699,6 @@ _timelineTutorial:
_2fa:
alreadyRegistered: "이미 설정이 완료되었습니다."
registerTOTP: "인증 앱 설정 시작"
passwordToTOTP: "비밀번호를 입력하세요."
step1: "먼저, {a}나 {b}등의 인증 앱을 사용 중인 디바이스에 설치합니다."
step2: "그 후, 표시되어 있는 QR코드를 앱으로 스캔합니다."
step2Click: "QR 코드를 클릭하면 기기에 설치된 인증 앱에 등록할 수 있습니다."

View File

@@ -411,6 +411,7 @@ aboutMisskey: "Sobre Misskey"
administrator: "Administrador"
token: "Símbolo"
2fa: "Autenticação de dois fatores"
setupOf2fa: "Configuração de autenticação de dois fatores"
totp: "Aplicativo Autenticador"
totpDescription: "Digite a senha de uso único informado pelo aplicativo autenticador"
moderator: "Moderador"
@@ -918,6 +919,7 @@ pleaseSelect: "Por favor, selecione."
reverse: "Inversão"
colored: "Colorido"
refreshInterval: "Intervalo de atualização"
label: "Etiqueta"
type: "Tipo"
speed: "Velocidade"
slow: "Lento"
@@ -1008,6 +1010,7 @@ waitingForMailAuth: "Verificação de e-mail pendente "
icon: "Avatar"
replies: "Responder"
renotes: "Repostar"
keepScreenOn: "Manter a tela do dispositivo sempre ligada"
_initialAccountSetting:
followUsers: "Siga usuários que lhe interessam para criar a sua linha do tempo."
_serverSettings:

View File

@@ -1608,7 +1608,6 @@ _timelineTutorial:
_2fa:
alreadyRegistered: "Двухфакторная аутентификация уже настроена."
registerTOTP: "Начните настраивать приложение-аутентификатор"
passwordToTOTP: "Пожалуйста, введите свой пароль"
step1: "Прежде всего, установите на устройство приложение для аутентификации, например, {a} или {b}."
step2: "Далее отсканируйте отображаемый QR-код при помощи приложения."
step2Click: "Нажав на QR-код, вы можете зарегистрироваться с помощью приложения для аутентификации или брелка для ключей, установленного на вашем устройстве."

View File

@@ -510,7 +510,6 @@ _sfx:
chat: "Chatt"
antenna: "Antenner"
_2fa:
passwordToTOTP: "Skriv in ditt lösenord"
renewTOTPCancel: "Nej tack"
_antennaSources:
all: "Alla noter"

View File

@@ -1102,6 +1102,8 @@ icon: "ไอคอน"
forYou: "สำหรับคุณ"
replies: "ตอบกลับ"
renotes: "รีโน้ต"
loadReplies: "แสดงการตอบกลับ"
loadConversation: "แสดงบทสนทนา"
_announcement:
forExistingUsersDescription: "การประกาศนี้จะแสดงต่อผู้ใช้ที่มีอยู่ ณ จุดที่เผยแพร่นั้นๆถ้าหากเปิดใช้งาน ถ้าหากปิดใช้งานผู้ที่กำลังสมัครใหม่หลังจากโพสต์แล้วนั้นก็จะเห็นเช่นกัน"
needConfirmationToReadDescription: "ข้อความแจ้งแยก ถ้าหากต้องการเพื่อยืนยันว่ากำลังทำเครื่องหมายประกาศนี้ว่าอ่านแล้วจะแสดงขึ้นถ้าหากเปิดใช้งาน การประกาศนั้นจะไม่รวมอยู่ในฟังก์ชั่นว่า \"ทำเครื่องหมายทั้งหมดว่าอ่านแล้ว\""
@@ -1382,6 +1384,8 @@ _achievements:
title: "Brain Diver"
description: "โพสต์ลิงก์ไปยัง Brain Diver"
flavor: "Misskey-Misskey La-Tu-Ma"
_smashTestNotificationButton:
title: "ทดสอบโอเวอร์โฟลว์"
_role:
new: "บทบาทใหม่"
edit: "แก้ไขบทบาท"
@@ -1692,7 +1696,6 @@ _timelineTutorial:
_2fa:
alreadyRegistered: "คุณได้ลงทะเบียนอุปกรณ์ยืนยันตัวตนแบบ 2 ชั้นแล้ว"
registerTOTP: "ลงทะเบียนแอพตัวตรวจสอบสิทธิ์"
passwordToTOTP: "กรอกรหัสผ่าน"
step1: "ขั้นตอนแรก ติดตั้งแอปยืนยันตัวตน (เช่น {a} หรือ {b}) บนอุปกรณ์ของคุณ"
step2: "จากนั้นสแกนรหัส QR ที่แสดงบนหน้าจอนี้"
step2Click: "การคลิกที่รหัส QR นี้จะช่วยให้คุณนั้นสามารถลงทะเบียน 2FA กับคีย์ความปลอดภัยหรือแอปตรวจสอบความถูกต้องของโทรศัพท์ได้"
@@ -1986,6 +1989,10 @@ _notification:
unreadAntennaNote: "เสาอากาศ {name}"
emptyPushNotificationMessage: "การแจ้งเตือนแบบพุชได้รับการอัพเดทแล้ว"
achievementEarned: "รับความสำเร็จ"
testNotification: "ทดสอบการแจ้งเตือน"
checkNotificationBehavior: "ตรวจสอบลักษณะที่ปรากฏการแจ้งเตือน"
sendTestNotification: "ส่งทดสอบการแจ้งเตือน"
notificationWillBeDisplayedLikeThis: "การแจ้งเตือนมีลักษณะแบบนี้"
_types:
all: "ทั้งหมด"
follow: "กำลังติดตาม"

View File

@@ -1,5 +1,5 @@
---
_lang_: "Tiếng Việt"
_lang_: "Tiếng Nhật"
headlineMisskey: "Mạng xã hội liên hợp"
introMisskey: "Xin chào! Misskey là một nền tảng tiểu blog phi tập trung mã nguồn mở.\nViết \"tút\" để chia sẻ những suy nghĩ của bạn 📡\nBằng \"biểu cảm\", bạn có thể bày tỏ nhanh chóng cảm xúc của bạn với các tút 👍\nHãy khám phá một thế giới mới! 🚀"
poweredByMisskeyDescription: "{name} là một trong những chủ máy của <b>Misskey</b> là nền tảng mã nguồn mở"
@@ -45,6 +45,7 @@ pin: "Ghim"
unpin: "Bỏ ghim"
copyContent: "Chép nội dung"
copyLink: "Chép liên kết"
copyLinkRenote: "Sao chép liên kết ghi chú"
delete: "Xóa"
deleteAndEdit: "Sửa"
deleteAndEditConfirm: "Bạn có chắc muốn sửa tút này? Những biểu cảm, lượt trả lời và đăng lại sẽ bị mất."
@@ -156,6 +157,7 @@ addEmoji: "Thêm emoji"
settingGuide: "Cài đặt đề xuất"
cacheRemoteFiles: "Tập tin cache từ xa"
cacheRemoteFilesDescription: "Khi tùy chọn này bị tắt, các tập tin từ xa sẽ được tải trực tiếp từ máy chủ khác. Điều này sẽ giúp giảm dung lượng lưu trữ nhưng lại tăng lưu lượng truy cập, vì hình thu nhỏ sẽ không được tạo."
youCanCleanRemoteFilesCache: "Bạn có thể xoá bộ nhớ đệm bằng cách nhấn vào nút🗑ở trong phần quản lý tệp."
cacheRemoteSensitiveFiles: "Lưu các tập tin nhạy cảm vào bộ nhớ tạm từ xa"
cacheRemoteSensitiveFilesDescription: "Khi bạn tắt tính năng này, các tệp nhạy cảm sẽ được tải trực tiếp từ máy chủ và không được lưu vào bộ nhớ tạm"
flagAsBot: "Đánh dấu đây là tài khoản bot"
@@ -409,10 +411,13 @@ aboutMisskey: "Về Misskey"
administrator: "Quản trị viên"
token: "Token"
2fa: "Xác thực 2 yếu tố"
setupOf2fa: "Thiết lập xác thực 2 yếu tố"
totp: "Ứng dụng xác thực"
totpDescription: "Nhắn mã OTP bằng ứng dụng xác thực"
moderator: "Kiểm duyệt viên"
moderation: "Kiểm duyệt"
moderationNote: "Ghi chú kiểm duyệt"
addModerationNote: "Thêm ghi chú kiểm duyệt"
nUsersMentioned: "Dùng bởi {n} người"
securityKeyAndPasskey: "Mã bảo mật・Passkey"
securityKey: "Khóa bảo mật"
@@ -988,11 +993,95 @@ copyErrorInfo: "Sao chép thông tin lỗi"
joinThisServer: "Đăng ký trên chủ máy này"
exploreOtherServers: "Tìm chủ máy khác"
letsLookAtTimeline: "Thử xem Timeline"
emailNotSupported: "Máy chủ này không hỗ trợ gửi email"
postToTheChannel: "Đăng lên kênh"
cannotBeChangedLater: "Không thể thay đổi sau này."
rolesAssignedToMe: "Vai trò được giao cho tôi"
resetPasswordConfirm: "Bạn thực sự muốn đặt lại mật khẩu?"
sensitiveWords: "Các từ nhạy cảm"
license: "Giấy phép"
unfavoriteConfirm: "Bạn thực sự muốn xoá khỏi mục yêu thích?"
retryAllQueuesConfirmText: "Điều này sẽ tạm thời làm tăng mức độ tải của máy chủ."
enableChartsForRemoteUser: "Tạo biểu đồ người dùng từ xa"
video: "Video"
videos: "Các video"
dataSaver: "Tiết kiệm dung lượng"
accountMigration: "Chuyển tài khoản"
accountMoved: "Người dùng này đã chuyển sang một tài khoản mới:"
accountMovedShort: "Tài khoản này đã được chuyển"
operationForbidden: "Thao tác này không thể thực hiện"
forceShowAds: "Luôn hiện quảng cáo"
notificationDisplay: "Thông báo"
leftTop: "Phía trên bên tráí"
rightTop: "Phía trên bên phải"
leftBottom: "Phía dưới bên trái"
rightBottom: "Phía dưới bên phải"
stackAxis: "Hướng chồng"
vertical: "Dọc"
horizontal: "Thanh bên"
position: "Vị trí"
serverRules: "Luật của máy chủ"
youFollowing: "Đang theo dõi"
later: "Để sau"
goToMisskey: "Tới Misskey"
installed: "Đã tải xuống"
branding: "Thương hiệu"
turnOffToImprovePerformance: "Tắt mục này có thể cải thiện hiệu năng."
expirationDate: "Ngày hết hạn"
noExpirationDate: "Vô thời hạn"
waitingForMailAuth: "Đang chờ xác nhận email"
unused: "Chưa được sử dụng"
used: "Đã được sử dụng"
expired: "Đã hết hạn"
doYouAgree: "Đồng ý?"
iHaveReadXCarefullyAndAgree: "Tôi đã đọc và đồng ý với \"x\"."
dialog: "Hộp thoại"
icon: "Ảnh đại diện"
forYou: "Dành cho bạn"
currentAnnouncements: "Thông báo hiện tại"
pastAnnouncements: "Thông báo trước đó"
youHaveUnreadAnnouncements: "Có thông báo chưa đọc."
replies: "Trả lời"
renotes: "Đăng lại"
loadReplies: "Hiển thị các trả lời"
pinnedList: "Các mục đã được ghim"
keepScreenOn: "Giữ màn hình luôn bật"
verifiedLink: "Chúng tôi đã xác nhận bạn là chủ sở hữu của đường dẫn này"
_announcement:
forExistingUsers: "Chỉ những người dùng đã tồn tại"
forExistingUsersDescription: "Nếu được bật, thông báo này sẽ chỉ hiển thị với những người dùng đã tồn tại vào lúc thông báo được tạo. Nếu tắt đi, những tài khoản mới đăng ký sau khi thông báo được đăng lên cũng sẽ thấy nó."
end: "Lưu trữ thông báo"
tooManyActiveAnnouncementDescription: "Có quá nhiều thông báo sẽ làm trải nghiệm của người dùng tệ đi. Vui lòng lưu trữ những thông báo đã hết hiệu lực."
readConfirmTitle: "Đánh dấu là đã đọc?"
readConfirmText: "Điều này sẽ đánh dấu nội dung của \"{title}\" là đã đọc."
_initialAccountSetting:
accountCreated: "Tài khoản của bạn đã được tạo thành công!"
letsStartAccountSetup: "Để bắt đầu, hãy cùng thiết lập tài khoản nhé."
letsFillYourProfile: "Đầu tiên, hãy thiết lập hồ sơ của bạn."
profileSetting: "Thiết lập hồ sơ"
privacySetting: "Cài đặt quyền riêng tư"
theseSettingsCanEditLater: "Bạn vẫn có thể thay đổi những cài đặt này."
youCanEditMoreSettingsInSettingsPageLater: "Còn rất nhiều những cài đặt khác bạn có thể thay đổi ở trang \"Cài đặt\". Hãy nhớ ghé thăm trong lần sau nhé."
followUsers: "Thử theo dõi một vài người mà bạn có thể thích để xây dựng dòng thời gian của mình."
pushNotificationDescription: "Bật thông báo đẩy sẽ cho phép bạn nhận thông báo từ {name} trực tiếp từ thiết bị của bạn."
initialAccountSettingCompleted: "Thiết lập tài khoản thành công!"
haveFun: "Hãy tận hưởng {name} nhé!"
ifYouNeedLearnMore: "Nếu bạn muốn tìm hiểu thêm về cách sử dụng {name} (Misskey), hãy vào {link}."
skipAreYouSure: "Bạn thực sự muốn bỏ qua mục thiết lập tài khoản?"
laterAreYouSure: "Bạn thực sự muốn thiết lập tài khoản vào lúc khác?"
_serverSettings:
iconUrl: "Biểu tượng URL"
appIconResolutionMustBe: "Độ phân giải tối thiểu là {resolution}."
manifestJsonOverride: "Ghi đè manifest.json"
_accountMigration:
moveFrom: "Chuyển một tài khoản khác vào tài khoản này"
moveFromLabel: "Tài khoản gốc #{n}"
moveTo: "Chuyển tài khoản này vào một tài khoản khác"
moveCannotBeUndone: "Việc chuyển tài khoản không thể huỷ."
moveAccountDescription: "Điều này sẽ chuyển tài khoản này sang một tài khoản khác.\n ・Những người theo dõi sẽ tự động được chuyển sang tài khoản mới\n ・Tài khoản này sẽ tự bỏ theo dõi những người mà bạn đã theo dõi trước đây\n ・Bạn sẽ không thể đăng tút mới, v.v trên tài khoản này\n\nDù việc chuyển người theo dõi được diễn ra tự động, bạn vẫn phải tự chuẩn bị một vài bước để chuyển danh sách những người dùng bạn đang theo dõi. Để làm vậy, vui lòng thực hiện việc xuất dữ liệu những người dùng đã theo dõi mà sau này bạn sẽ dùng để nhập vào tài khoản mới ở menu Cài đặt. Hành động tương tự áp dụng với danh sách những người dùng bị chặn hoặc tắt tiếng.\n\n(Điều này áp dụng cho phiên bản Misskey v13.12.0 và sau này. Các phần mềm ActivityPub khác , ví dụ như Mastodon, sẽ có thể hoạt động khác đi.)"
startMigration: "Chuyển"
movedAndCannotBeUndone: "\nTài khoản này đã được chuyển đi.\nViệc di chuyển tài khoản không thể bị huỷ bỏ."
movedTo: "Tài khoản mới:"
_achievements:
earnedAt: "Ngày thu nhận"
_types:
@@ -1031,6 +1120,8 @@ _achievements:
title: "Hàng tinh đăng bài"
description: "Đã đăng bài 50,000 lần rồi"
_notes100000:
title: "ALL YOUR NOTE ARE BELONG TO US"
description: "Đăng 100,000 tút"
flavor: "Liệu viết bài gì tầm này vậy? "
_login3:
title: "Sơ cấp I"
@@ -1062,6 +1153,15 @@ _achievements:
_login400:
title: "Khách hàng thường xuyên cấp III"
description: "Tổng số ngày đăng nhập đạt 400 ngày"
_login1000:
flavor: "Cảm ơn bạn đã sử dụng Misskey!"
_noteFavorited1:
title: "Nhà thiên văn học"
_myNoteFavorited1:
title: "Đi tìm những ngôi sao"
_profileFilled:
title: "Luôn sẵn sàng"
description: "Thiết lập tài khoản của bạn"
_markedAsCat:
title: "Tôi là một con mèo"
description: "Bật chế độ mèo"
@@ -1087,8 +1187,18 @@ _achievements:
_followers10:
title: "FOLLOW ME!!"
description: "Người theo dõi bạn vượt lên 10 người"
_followers50:
title: "Từng chút một"
description: "Đạt được 50 lượt theo dõi"
_followers100:
title: "Người nổi tiếng"
description: "Đạt được 100 lượt theo dõi"
_followers300:
title: "Vui lòng xếp thành hàng nào"
description: "Đạt được 300 lượt theo dõi"
_followers500:
title: "Trạm phát sóng"
description: "Đạt được 500 lượt theo dõi"
_followers1000:
title: "Người có tầm ảnh hưởng"
description: "Người theo dõi bạn vượt lên 1000 người"
@@ -1107,11 +1217,15 @@ _achievements:
description: "Tìm thấy được những kho báu cất giấu"
_client30min:
title: "Giải lao xỉu"
description: "Giữ Misskey mở trong ít nhất 30 phút"
_client60min:
description: "Giữ Misskey mở trong ít nhất 60 phút"
_noteDeletedWithin1min:
title: "Xem như không có gì đâu nha"
_postedAtLateNight:
title: "Loài ăn đêm"
description: "Đăng bài trong đêm khuya "
flavor: "Đến giờ đi ngủ rồi."
_postedAt0min0sec:
title: "Tín hiệu báo giờ"
description: "Đăng bài vào 0 phút 0 giây"
@@ -1142,6 +1256,8 @@ _achievements:
_setNameToSyuilo:
title: "Ngưỡng mộ với vị thần"
description: "Đạt tên là syuilo"
_passedSinceAccountCreated1:
title: "Kỷ niệm một năm"
_loggedInOnBirthday:
title: "Sinh nhật vủi vẻ"
description: "Đăng nhập vào ngày sinh"
@@ -1401,7 +1517,6 @@ _timelineTutorial:
_2fa:
alreadyRegistered: "Bạn đã đăng ký thiết bị xác minh 2 bước."
registerTOTP: "Đăng ký ứng dụng xác thực"
passwordToTOTP: "Nhắn mật mã"
step1: "Trước tiên, hãy cài đặt một ứng dụng xác minh (chẳng hạn như {a} hoặc {b}) trên thiết bị của bạn."
step2: "Sau đó, quét mã QR hiển thị trên màn hình này."
step2Click: "Quét mã QR trên ứng dụng xác thực (Authy, Google authenticator, v.v.)"

View File

@@ -1109,6 +1109,13 @@ youHaveUnreadAnnouncements: "您有未读的公告"
useSecurityKey: "请根据浏览器或设备的提示,使用安全密钥或通行密钥。"
replies: "回复"
renotes: "转发"
loadReplies: "查看回复"
loadConversation: "查看对话"
pinnedList: "已置顶的列表"
keepScreenOn: "保持设备屏幕开启"
verifiedLink: "已验证的链接"
notifyNotes: "打开发帖通知"
unnotifyNotes: "关闭发帖通知"
_announcement:
forExistingUsers: "仅限现有用户"
forExistingUsersDescription: "若启用,该公告将仅对创建此公告时存在的用户可见。 如果禁用,则在创建此公告后注册的用户也可以看到该公告。"
@@ -1137,9 +1144,11 @@ _serverRules:
description: "在新用户注册前显示服务器的简单规则。推荐显示服务条款的主要内容。"
_serverSettings:
iconUrl: "图标 URL"
appIconUsageExample: "例如PWA和新增至手机主屏幕的书签。"
appIconStyleRecommendation: "因为可能会被裁切为圆形或者圆角图形,所以建议将背景用单色填充。"
appIconResolutionMustBe: "分辨率必须符合{resolution}。"
appIconDescription: "指定当 {host} 显示为 app 时的图标。"
appIconUsageExample: "例如:作为书签添加到 PWA 或手机主屏幕的时候"
appIconStyleRecommendation: "因为有可能会被裁切为圆形或者圆角矩形,建议使用边缘带有留白背景的图标。"
appIconResolutionMustBe: "分辨率必须为 {resolution}。"
manifestJsonOverride: "覆盖 mainfest.json"
_accountMigration:
moveFrom: "从别的账号迁移到此账户"
moveFromSub: "为另一个账户建立别名"
@@ -1707,7 +1716,6 @@ _timelineTutorial:
_2fa:
alreadyRegistered: "此设备已被注册"
registerTOTP: "开始设置认证应用"
passwordToTOTP: "请输入您的密码"
step1: "首先,在您的设备上安装验证应用,例如 {a} 或 {b}。"
step2: "然后,扫描屏幕上显示的二维码。"
step2Click: "通过点击二维码,您可以使用设备上安装的身份验证器应用程序或密钥环进行注册"
@@ -1885,6 +1893,7 @@ _profile:
metadataContent: "内容"
changeAvatar: "修改头像"
changeBanner: "修改横幅"
verifiedLinkDescription: "如果将内容设置为 URL当链接所指向的网页内包含自己的个人资料链接时可以显示一个已验证图标。"
_exportOrImport:
allNotes: "所有帖子"
favoritedNotes: "收藏的帖子"
@@ -2003,6 +2012,7 @@ _notification:
youReceivedFollowRequest: "您有新的关注请求"
yourFollowRequestAccepted: "您的关注请求已通过"
pollEnded: "问卷调查结果已生成。"
newNote: "新的帖子"
unreadAntennaNote: "天线 {name}"
emptyPushNotificationMessage: "推送通知已更新"
achievementEarned: "获得成就"

View File

@@ -15,7 +15,7 @@ gotIt: "知道了"
cancel: "取消"
noThankYou: "現在不要"
enterUsername: "輸入使用者名稱"
renotedBy: "{user} 轉傳了"
renotedBy: "{user} 轉"
noNotes: "無貼文"
noNotifications: "沒有通知"
instance: "伺服器"
@@ -106,10 +106,10 @@ unfollow: "取消追隨"
followRequestPending: "追隨許可待批准"
enterEmoji: "輸入表情符號"
renote: "轉發"
unrenote: "取消轉"
renoted: "轉成功"
cantRenote: "無法轉此貼文。"
cantReRenote: "無法轉之前已經轉過的內容。"
unrenote: "取消轉"
renoted: "轉成功"
cantRenote: "無法轉此貼文。"
cantReRenote: "無法轉之前已經轉過的內容。"
quote: "引用"
inChannelRenote: "在頻道內轉發"
inChannelQuote: "在頻道內引用"
@@ -546,7 +546,7 @@ recentUsed: "最近使用"
install: "安裝"
uninstall: "解除安裝"
installedApps: "已授權的應用程式"
nothing: ""
nothing: "查無項目"
installedDate: "安裝時間"
lastUsedDate: "最後上線日期"
state: "狀態"
@@ -657,7 +657,7 @@ behavior: "行為"
sample: "範例"
abuseReports: "檢舉"
reportAbuse: "檢舉"
reportAbuseRenote: "檢舉轉"
reportAbuseRenote: "檢舉轉發貼文"
reportAbuseOf: "檢舉{name}"
fillAbuseReportDescription: "請填寫檢舉的詳細理由。如有需要,請附上相關 URL。"
abuseReported: "檢舉完成。感謝您的報告。"
@@ -1111,6 +1111,11 @@ replies: "回覆"
renotes: "轉發"
loadReplies: "閱覽回覆"
loadConversation: "閱覽對話"
pinnedList: "已置頂的清單"
keepScreenOn: "保持設備螢幕開啟"
verifiedLink: "已驗證連結"
notifyNotes: "開啟貼文通知"
unnotifyNotes: "關閉貼文通知"
_announcement:
forExistingUsers: "僅限既有的使用者"
forExistingUsersDescription: "啟用代表僅向現存使用者顯示;停用代表張貼後註冊的新使用者也會看到。"
@@ -1686,7 +1691,7 @@ _ago:
future: "未來"
justNow: "剛剛"
secondsAgo: "{n} 秒前"
minutesAgo: "{n}分鐘前 "
minutesAgo: "{n} 分鐘前 "
hoursAgo: "{n} 小時前"
daysAgo: "{n} 天前"
weeksAgo: "{n} 週前"
@@ -1711,7 +1716,6 @@ _timelineTutorial:
_2fa:
alreadyRegistered: "此裝置已被註冊過了"
registerTOTP: "開始設定驗證應用程式"
passwordToTOTP: "請輸入密碼"
step1: "首先,在您的裝置上安裝驗證程式,例如 {a} 或 {b}。"
step2: "然後,掃描螢幕上的 QR 碼。"
step2Click: "您可以點擊 QR 碼,以使用裝置上的驗證應用程式或金鑰環註冊。"
@@ -1889,6 +1893,7 @@ _profile:
metadataContent: "内容"
changeAvatar: "更換大頭貼"
changeBanner: "變更橫幅圖像"
verifiedLinkDescription: "如果輸入包含您個人資料的網站 URL欄位旁邊將出現驗證圖示。"
_exportOrImport:
allNotes: "所有貼文"
favoritedNotes: "「我的最愛」貼文"
@@ -2007,6 +2012,7 @@ _notification:
youReceivedFollowRequest: "您有新的追隨請求"
yourFollowRequestAccepted: "您的追隨請求已通過"
pollEnded: "問卷調查已產生結果"
newNote: "新的貼文"
unreadAntennaNote: "天線 {name}"
emptyPushNotificationMessage: "推送通知已更新"
achievementEarned: "獲得成就"

View File

@@ -1,12 +1,12 @@
{
"name": "misskey",
"version": "2023.9.0-beta.8",
"version": "2023.9.0-beta.11",
"codename": "nasubi",
"repository": {
"type": "git",
"url": "https://github.com/misskey-dev/misskey.git"
},
"packageManager": "pnpm@8.7.5",
"packageManager": "pnpm@8.7.6",
"workspaces": [
"packages/frontend",
"packages/backend",
@@ -46,17 +46,17 @@
"execa": "8.0.1",
"cssnano": "6.0.1",
"js-yaml": "4.1.0",
"postcss": "8.4.29",
"terser": "5.19.4",
"postcss": "8.4.30",
"terser": "5.20.0",
"typescript": "5.2.2"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "6.7.0",
"@typescript-eslint/parser": "6.7.0",
"@typescript-eslint/eslint-plugin": "6.7.2",
"@typescript-eslint/parser": "6.7.2",
"cross-env": "7.0.3",
"cypress": "13.2.0",
"eslint": "8.49.0",
"start-server-and-test": "2.0.0"
"start-server-and-test": "2.0.1"
},
"optionalDependencies": {
"@tensorflow/tfjs-core": "4.4.0"

View File

@@ -0,0 +1,10 @@
export class UserBlacklistAnntena1689325027964 {
name = 'UserBlacklistAnntena1689325027964'
async up(queryRunner) {
await queryRunner.query(`ALTER TYPE "antenna_src_enum" ADD VALUE 'users_blacklist' AFTER 'list'`);
}
async down(queryRunner) {
}
}

View File

@@ -0,0 +1,11 @@
export class VerifiedLinks1695260774117 {
name = 'VerifiedLinks1695260774117'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "user_profile" ADD "verifiedLinks" character varying array NOT NULL DEFAULT '{}'`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "verifiedLinks"`);
}
}

View File

@@ -0,0 +1,13 @@
export class FollowingNotify1695288787870 {
name = 'FollowingNotify1695288787870'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "following" ADD "notify" character varying(32)`);
await queryRunner.query(`CREATE INDEX "IDX_5108098457488634a4768e1d12" ON "following" ("notify") `);
}
async down(queryRunner) {
await queryRunner.query(`DROP INDEX "public"."IDX_5108098457488634a4768e1d12"`);
await queryRunner.query(`ALTER TABLE "following" DROP COLUMN "notify"`);
}
}

View File

@@ -58,19 +58,19 @@
"dependencies": {
"@aws-sdk/client-s3": "3.412.0",
"@aws-sdk/lib-storage": "3.412.0",
"@smithy/node-http-handler": "2.1.3",
"@bull-board/api": "5.8.3",
"@bull-board/fastify": "5.8.3",
"@bull-board/ui": "5.8.3",
"@smithy/node-http-handler": "2.1.5",
"@bull-board/api": "5.8.4",
"@bull-board/fastify": "5.8.4",
"@bull-board/ui": "5.8.4",
"@discordapp/twemoji": "14.1.2",
"@fastify/accepts": "4.2.0",
"@fastify/cookie": "9.0.4",
"@fastify/cors": "8.3.0",
"@fastify/cookie": "9.1.0",
"@fastify/cors": "8.4.0",
"@fastify/express": "2.3.0",
"@fastify/http-proxy": "9.2.1",
"@fastify/multipart": "7.7.3",
"@fastify/static": "6.11.1",
"@fastify/view": "8.1.0",
"@fastify/static": "6.11.2",
"@fastify/view": "8.2.0",
"@nestjs/common": "10.2.5",
"@nestjs/core": "10.2.5",
"@nestjs/testing": "10.2.5",
@@ -78,7 +78,7 @@
"@simplewebauthn/server": "8.1.1",
"@sinonjs/fake-timers": "11.1.0",
"@swc/cli": "0.1.62",
"@swc/core": "1.3.84",
"@swc/core": "1.3.87",
"accepts": "1.3.8",
"ajv": "8.12.0",
"archiver": "6.0.1",
@@ -86,7 +86,7 @@
"bcryptjs": "2.4.3",
"blurhash": "2.0.5",
"body-parser": "1.20.2",
"bullmq": "4.10.0",
"bullmq": "4.11.3",
"cacheable-lookup": "7.0.0",
"cbor": "9.0.1",
"chalk": "5.3.0",
@@ -149,16 +149,16 @@
"rss-parser": "3.13.0",
"rxjs": "7.8.1",
"sanitize-html": "2.11.0",
"sharp": "0.32.5",
"sharp": "0.32.6",
"sharp-read-bmp": "github:misskey-dev/sharp-read-bmp",
"slacc": "0.0.10",
"strict-event-emitter-types": "2.0.0",
"stringz": "2.1.0",
"summaly": "github:misskey-dev/summaly",
"systeminformation": "5.21.5",
"systeminformation": "5.21.8",
"tinycolor2": "1.6.0",
"tmp": "0.2.1",
"tsc-alias": "1.8.7",
"tsc-alias": "1.8.8",
"tsconfig-paths": "4.2.0",
"twemoji-parser": "14.0.0",
"typeorm": "0.3.17",
@@ -166,7 +166,7 @@
"ulid": "2.3.0",
"vary": "1.1.2",
"web-push": "3.6.6",
"ws": "8.14.1",
"ws": "8.14.2",
"xev": "3.0.2"
},
"devDependencies": {
@@ -175,21 +175,21 @@
"@swc/jest": "0.2.29",
"@types/accepts": "1.3.5",
"@types/archiver": "5.3.2",
"@types/bcryptjs": "2.4.3",
"@types/body-parser": "1.19.2",
"@types/bcryptjs": "2.4.4",
"@types/body-parser": "1.19.3",
"@types/cbor": "6.0.0",
"@types/color-convert": "2.0.1",
"@types/content-disposition": "0.5.6",
"@types/fluent-ffmpeg": "2.1.22",
"@types/http-link-header": "1.0.3",
"@types/jest": "29.5.4",
"@types/js-yaml": "4.0.5",
"@types/jsdom": "21.1.2",
"@types/jsonld": "1.5.9",
"@types/jsrsasign": "10.5.8",
"@types/jest": "29.5.5",
"@types/js-yaml": "4.0.6",
"@types/jsdom": "21.1.3",
"@types/jsonld": "1.5.10",
"@types/jsrsasign": "10.5.9",
"@types/mime-types": "2.1.1",
"@types/ms": "0.7.31",
"@types/node": "20.6.0",
"@types/node": "20.6.3",
"@types/node-fetch": "3.0.3",
"@types/nodemailer": "6.4.10",
"@types/oauth": "0.9.2",
@@ -212,8 +212,8 @@
"@types/vary": "1.1.0",
"@types/web-push": "3.6.0",
"@types/ws": "8.5.5",
"@typescript-eslint/eslint-plugin": "6.7.0",
"@typescript-eslint/parser": "6.7.0",
"@typescript-eslint/eslint-plugin": "6.7.2",
"@typescript-eslint/parser": "6.7.2",
"aws-sdk-client-mock": "3.0.0",
"cross-env": "7.0.3",
"eslint": "8.49.0",

View File

@@ -8,7 +8,7 @@ import { IsNull, In, MoreThan, Not } from 'typeorm';
import { bindThis } from '@/decorators.js';
import { DI } from '@/di-symbols.js';
import type { MiLocalUser, MiRemoteUser, MiUser } from '@/models/entities/User.js';
import type { MiLocalUser, MiRemoteUser, MiUser } from '@/models/User.js';
import type { BlockingsRepository, FollowingsRepository, InstancesRepository, MutingsRepository, UserListJoiningsRepository, UsersRepository } from '@/models/_.js';
import type { RelationshipJobData, ThinUser } from '@/queue/types.js';

View File

@@ -6,7 +6,7 @@
import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { UsersRepository } from '@/models/_.js';
import type { MiUser } from '@/models/entities/User.js';
import type { MiUser } from '@/models/User.js';
import { ApRendererService } from '@/core/activitypub/ApRendererService.js';
import { RelayService } from '@/core/RelayService.js';
import { ApDeliverManagerService } from '@/core/activitypub/ApDeliverManagerService.js';

View File

@@ -5,7 +5,7 @@
import { Inject, Injectable } from '@nestjs/common';
import type { UserProfilesRepository } from '@/models/_.js';
import type { MiUser } from '@/models/entities/User.js';
import type { MiUser } from '@/models/User.js';
import { DI } from '@/di-symbols.js';
import { bindThis } from '@/decorators.js';
import { NotificationService } from '@/core/NotificationService.js';

View File

@@ -6,7 +6,7 @@
import { Inject, Injectable } from '@nestjs/common';
import { Brackets } from 'typeorm';
import { DI } from '@/di-symbols.js';
import type { MiUser } from '@/models/entities/User.js';
import type { MiUser } from '@/models/User.js';
import type { AnnouncementReadsRepository, AnnouncementsRepository, MiAnnouncement, MiAnnouncementRead } from '@/models/_.js';
import { bindThis } from '@/decorators.js';
import { Packed } from '@/misc/json-schema.js';

View File

@@ -5,9 +5,9 @@
import { Inject, Injectable } from '@nestjs/common';
import * as Redis from 'ioredis';
import type { MiAntenna } from '@/models/entities/Antenna.js';
import type { MiNote } from '@/models/entities/Note.js';
import type { MiUser } from '@/models/entities/User.js';
import type { MiAntenna } from '@/models/Antenna.js';
import type { MiNote } from '@/models/Note.js';
import type { MiUser } from '@/models/User.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import * as Acct from '@/misc/acct.js';
import type { Packed } from '@/misc/json-schema.js';
@@ -119,6 +119,12 @@ export class AntennaService implements OnApplicationShutdown {
return this.utilityService.getFullApAccount(username, host).toLowerCase();
});
if (!accts.includes(this.utilityService.getFullApAccount(noteUser.username, noteUser.host).toLowerCase())) return false;
} else if (antenna.src === 'users_blacklist') {
const accts = antenna.users.map(x => {
const { username, host } = Acct.parse(x);
return this.utilityService.getFullApAccount(username, host).toLowerCase();
});
if (accts.includes(this.utilityService.getFullApAccount(noteUser.username, noteUser.host).toLowerCase())) return false;
}
const keywords = antenna.keywords

View File

@@ -7,7 +7,7 @@ import { Inject, Injectable } from '@nestjs/common';
import * as Redis from 'ioredis';
import type { BlockingsRepository, ChannelFollowingsRepository, FollowingsRepository, MutingsRepository, RenoteMutingsRepository, MiUserProfile, UserProfilesRepository, UsersRepository } from '@/models/_.js';
import { MemoryKVCache, RedisKVCache } from '@/misc/cache.js';
import type { MiLocalUser, MiUser } from '@/models/entities/User.js';
import type { MiLocalUser, MiUser } from '@/models/User.js';
import { DI } from '@/di-symbols.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { bindThis } from '@/decorators.js';

View File

@@ -0,0 +1,159 @@
/*
* SPDX-FileCopyrightText: syuilo and other misskey contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { Inject, Injectable } from '@nestjs/common';
import { QueryFailedError } from 'typeorm';
import { DI } from '@/di-symbols.js';
import type { ClipsRepository, MiNote, MiClip, ClipNotesRepository, NotesRepository } from '@/models/_.js';
import { bindThis } from '@/decorators.js';
import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error.js';
import { RoleService } from '@/core/RoleService.js';
import { IdService } from '@/core/IdService.js';
import type { MiLocalUser } from '@/models/User.js';
@Injectable()
export class ClipService {
public static NoSuchNoteError = class extends Error {};
public static NoSuchClipError = class extends Error {};
public static AlreadyAddedError = class extends Error {};
public static TooManyClipNotesError = class extends Error {};
public static TooManyClipsError = class extends Error {};
constructor(
@Inject(DI.clipsRepository)
private clipsRepository: ClipsRepository,
@Inject(DI.clipNotesRepository)
private clipNotesRepository: ClipNotesRepository,
@Inject(DI.notesRepository)
private notesRepository: NotesRepository,
private roleService: RoleService,
private idService: IdService,
) {
}
@bindThis
public async create(me: MiLocalUser, name: string, isPublic: boolean, description: string | null): Promise<MiClip> {
const currentCount = await this.clipsRepository.countBy({
userId: me.id,
});
if (currentCount > (await this.roleService.getUserPolicies(me.id)).clipLimit) {
throw new ClipService.TooManyClipsError();
}
const clip = await this.clipsRepository.insert({
id: this.idService.genId(),
createdAt: new Date(),
userId: me.id,
name: name,
isPublic: isPublic,
description: description,
}).then(x => this.clipsRepository.findOneByOrFail(x.identifiers[0]));
return clip;
}
@bindThis
public async update(me: MiLocalUser, clipId: MiClip['id'], name: string | undefined, isPublic: boolean | undefined, description: string | null | undefined): Promise<void> {
const clip = await this.clipsRepository.findOneBy({
id: clipId,
userId: me.id,
});
if (clip == null) {
throw new ClipService.NoSuchClipError();
}
await this.clipsRepository.update(clip.id, {
name: name,
description: description,
isPublic: isPublic,
});
}
@bindThis
public async delete(me: MiLocalUser, clipId: MiClip['id']): Promise<void> {
const clip = await this.clipsRepository.findOneBy({
id: clipId,
userId: me.id,
});
if (clip == null) {
throw new ClipService.NoSuchClipError();
}
await this.clipsRepository.delete(clip.id);
}
@bindThis
public async addNote(me: MiLocalUser, clipId: MiClip['id'], noteId: MiNote['id']): Promise<void> {
const clip = await this.clipsRepository.findOneBy({
id: clipId,
userId: me.id,
});
if (clip == null) {
throw new ClipService.NoSuchClipError();
}
const currentCount = await this.clipNotesRepository.countBy({
clipId: clip.id,
});
if (currentCount > (await this.roleService.getUserPolicies(me.id)).noteEachClipsLimit) {
throw new ClipService.TooManyClipNotesError();
}
try {
await this.clipNotesRepository.insert({
id: this.idService.genId(),
noteId: noteId,
clipId: clip.id,
});
} catch (e: unknown) {
if (e instanceof QueryFailedError) {
if (isDuplicateKeyValueError(e)) {
throw new ClipService.AlreadyAddedError();
} else if (e.driverError.detail.includes('is not present in table "note".')) {
throw new ClipService.NoSuchNoteError();
}
}
throw e;
}
this.clipsRepository.update(clip.id, {
lastClippedAt: new Date(),
});
this.notesRepository.increment({ id: noteId }, 'clippedCount', 1);
}
@bindThis
public async removeNote(me: MiLocalUser, clipId: MiClip['id'], noteId: MiNote['id']): Promise<void> {
const clip = await this.clipsRepository.findOneBy({
id: clipId,
userId: me.id,
});
if (clip == null) {
throw new ClipService.NoSuchClipError();
}
const note = await this.notesRepository.findOneBy({ id: noteId });
if (note == null) {
throw new ClipService.NoSuchNoteError();
}
await this.clipNotesRepository.delete({
noteId: noteId,
clipId: clip.id,
});
this.notesRepository.decrement({ id: noteId }, 'clippedCount', 1);
}
}

View File

@@ -51,12 +51,14 @@ import { UserKeypairService } from './UserKeypairService.js';
import { UserListService } from './UserListService.js';
import { UserMutingService } from './UserMutingService.js';
import { UserSuspendService } from './UserSuspendService.js';
import { UserAuthService } from './UserAuthService.js';
import { VideoProcessingService } from './VideoProcessingService.js';
import { WebhookService } from './WebhookService.js';
import { ProxyAccountService } from './ProxyAccountService.js';
import { UtilityService } from './UtilityService.js';
import { FileInfoService } from './FileInfoService.js';
import { SearchService } from './SearchService.js';
import { ClipService } from './ClipService.js';
import { ChartLoggerService } from './chart/ChartLoggerService.js';
import FederationChart from './chart/charts/federation.js';
import NotesChart from './chart/charts/notes.js';
@@ -176,11 +178,13 @@ const $UserKeypairService: Provider = { provide: 'UserKeypairService', useExisti
const $UserListService: Provider = { provide: 'UserListService', useExisting: UserListService };
const $UserMutingService: Provider = { provide: 'UserMutingService', useExisting: UserMutingService };
const $UserSuspendService: Provider = { provide: 'UserSuspendService', useExisting: UserSuspendService };
const $UserAuthService: Provider = { provide: 'UserAuthService', useExisting: UserAuthService };
const $VideoProcessingService: Provider = { provide: 'VideoProcessingService', useExisting: VideoProcessingService };
const $WebhookService: Provider = { provide: 'WebhookService', useExisting: WebhookService };
const $UtilityService: Provider = { provide: 'UtilityService', useExisting: UtilityService };
const $FileInfoService: Provider = { provide: 'FileInfoService', useExisting: FileInfoService };
const $SearchService: Provider = { provide: 'SearchService', useExisting: SearchService };
const $ClipService: Provider = { provide: 'ClipService', useExisting: ClipService };
const $ChartLoggerService: Provider = { provide: 'ChartLoggerService', useExisting: ChartLoggerService };
const $FederationChart: Provider = { provide: 'FederationChart', useExisting: FederationChart };
@@ -304,11 +308,13 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
UserListService,
UserMutingService,
UserSuspendService,
UserAuthService,
VideoProcessingService,
WebhookService,
UtilityService,
FileInfoService,
SearchService,
ClipService,
ChartLoggerService,
FederationChart,
NotesChart,
@@ -425,11 +431,13 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
$UserListService,
$UserMutingService,
$UserSuspendService,
$UserAuthService,
$VideoProcessingService,
$WebhookService,
$UtilityService,
$FileInfoService,
$SearchService,
$ClipService,
$ChartLoggerService,
$FederationChart,
$NotesChart,
@@ -547,11 +555,13 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
UserListService,
UserMutingService,
UserSuspendService,
UserAuthService,
VideoProcessingService,
WebhookService,
UtilityService,
FileInfoService,
SearchService,
ClipService,
FederationChart,
NotesChart,
UsersChart,
@@ -667,11 +677,13 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
$UserListService,
$UserMutingService,
$UserSuspendService,
$UserAuthService,
$VideoProcessingService,
$WebhookService,
$UtilityService,
$FileInfoService,
$SearchService,
$ClipService,
$FederationChart,
$NotesChart,
$UsersChart,

View File

@@ -8,11 +8,11 @@ import { Inject, Injectable } from '@nestjs/common';
import bcrypt from 'bcryptjs';
import { IsNull, DataSource } from 'typeorm';
import { genRsaKeyPair } from '@/misc/gen-key-pair.js';
import { MiUser } from '@/models/entities/User.js';
import { MiUserProfile } from '@/models/entities/UserProfile.js';
import { MiUser } from '@/models/User.js';
import { MiUserProfile } from '@/models/UserProfile.js';
import { IdService } from '@/core/IdService.js';
import { MiUserKeypair } from '@/models/entities/UserKeypair.js';
import { MiUsedUsername } from '@/models/entities/UsedUsername.js';
import { MiUserKeypair } from '@/models/UserKeypair.js';
import { MiUsedUsername } from '@/models/UsedUsername.js';
import { DI } from '@/di-symbols.js';
import generateNativeUserToken from '@/misc/generate-native-user-token.js';
import { bindThis } from '@/decorators.js';

View File

@@ -10,8 +10,8 @@ import { DI } from '@/di-symbols.js';
import { IdService } from '@/core/IdService.js';
import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import type { MiDriveFile } from '@/models/entities/DriveFile.js';
import type { MiEmoji } from '@/models/entities/Emoji.js';
import type { MiDriveFile } from '@/models/DriveFile.js';
import type { MiEmoji } from '@/models/Emoji.js';
import type { EmojisRepository, MiRole } from '@/models/_.js';
import { bindThis } from '@/decorators.js';
import { MemoryKVCache, RedisSingleCache } from '@/misc/cache.js';

View File

@@ -14,9 +14,9 @@ import { DI } from '@/di-symbols.js';
import type { DriveFilesRepository, UsersRepository, DriveFoldersRepository, UserProfilesRepository } from '@/models/_.js';
import type { Config } from '@/config.js';
import Logger from '@/logger.js';
import type { MiRemoteUser, MiUser } from '@/models/entities/User.js';
import type { MiRemoteUser, MiUser } from '@/models/User.js';
import { MetaService } from '@/core/MetaService.js';
import { MiDriveFile } from '@/models/entities/DriveFile.js';
import { MiDriveFile } from '@/models/DriveFile.js';
import { IdService } from '@/core/IdService.js';
import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error.js';
import { FILE_TYPE_BROWSERSAFE } from '@/const.js';
@@ -27,7 +27,7 @@ import { VideoProcessingService } from '@/core/VideoProcessingService.js';
import { ImageProcessingService } from '@/core/ImageProcessingService.js';
import type { IImage } from '@/core/ImageProcessingService.js';
import { QueueService } from '@/core/QueueService.js';
import type { MiDriveFolder } from '@/models/entities/DriveFolder.js';
import type { MiDriveFolder } from '@/models/DriveFolder.js';
import { createTemp } from '@/misc/create-temp.js';
import DriveChart from '@/core/chart/charts/drive.js';
import PerUserDriveChart from '@/core/chart/charts/per-user-drive.js';

View File

@@ -6,7 +6,7 @@
import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';
import * as Redis from 'ioredis';
import type { InstancesRepository } from '@/models/_.js';
import type { MiInstance } from '@/models/entities/Instance.js';
import type { MiInstance } from '@/models/Instance.js';
import { MemoryKVCache, RedisKVCache } from '@/misc/cache.js';
import { IdService } from '@/core/IdService.js';
import { DI } from '@/di-symbols.js';

View File

@@ -8,7 +8,7 @@ import { Inject, Injectable } from '@nestjs/common';
import { JSDOM } from 'jsdom';
import tinycolor from 'tinycolor2';
import * as Redis from 'ioredis';
import type { MiInstance } from '@/models/entities/Instance.js';
import type { MiInstance } from '@/models/Instance.js';
import type Logger from '@/logger.js';
import { DI } from '@/di-symbols.js';
import { LoggerService } from '@/core/LoggerService.js';

View File

@@ -5,10 +5,10 @@
import { Inject, Injectable } from '@nestjs/common';
import * as Redis from 'ioredis';
import type { MiUser } from '@/models/entities/User.js';
import type { MiNote } from '@/models/entities/Note.js';
import type { MiUserList } from '@/models/entities/UserList.js';
import type { MiAntenna } from '@/models/entities/Antenna.js';
import type { MiUser } from '@/models/User.js';
import type { MiNote } from '@/models/Note.js';
import type { MiUserList } from '@/models/UserList.js';
import type { MiAntenna } from '@/models/Antenna.js';
import type {
StreamChannels,
AdminStreamTypes,

View File

@@ -5,10 +5,10 @@
import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { MiUser } from '@/models/entities/User.js';
import type { MiUser } from '@/models/User.js';
import { normalizeForSearch } from '@/misc/normalize-for-search.js';
import { IdService } from '@/core/IdService.js';
import type { MiHashtag } from '@/models/entities/Hashtag.js';
import type { MiHashtag } from '@/models/Hashtag.js';
import type { HashtagsRepository } from '@/models/_.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { bindThis } from '@/decorators.js';

View File

@@ -5,7 +5,7 @@
import { Inject, Injectable } from '@nestjs/common';
import { IsNull } from 'typeorm';
import type { MiLocalUser } from '@/models/entities/User.js';
import type { MiLocalUser } from '@/models/User.js';
import type { UsersRepository } from '@/models/_.js';
import { MemorySingleCache } from '@/misc/cache.js';
import { DI } from '@/di-symbols.js';

View File

@@ -7,7 +7,7 @@ import { Inject, Injectable } from '@nestjs/common';
import { DataSource } from 'typeorm';
import * as Redis from 'ioredis';
import { DI } from '@/di-symbols.js';
import { MiMeta } from '@/models/entities/Meta.js';
import { MiMeta } from '@/models/Meta.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import { bindThis } from '@/decorators.js';
import { StreamMessages } from '@/server/api/stream/types.js';

View File

@@ -10,7 +10,7 @@ import { Window } from 'happy-dom';
import { DI } from '@/di-symbols.js';
import type { Config } from '@/config.js';
import { intersperse } from '@/misc/prelude/array.js';
import type { IMentionedRemoteUsers } from '@/models/entities/Note.js';
import type { IMentionedRemoteUsers } from '@/models/Note.js';
import { bindThis } from '@/decorators.js';
import * as TreeAdapter from '../../node_modules/parse5/dist/tree-adapters/default.js';
import type * as mfm from 'mfm-js';

View File

@@ -6,7 +6,7 @@
import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { ModerationLogsRepository } from '@/models/_.js';
import type { MiUser } from '@/models/entities/User.js';
import type { MiUser } from '@/models/User.js';
import { IdService } from '@/core/IdService.js';
import { bindThis } from '@/decorators.js';

View File

@@ -12,22 +12,22 @@ import RE2 from 're2';
import { extractMentions } from '@/misc/extract-mentions.js';
import { extractCustomEmojisFromMfm } from '@/misc/extract-custom-emojis-from-mfm.js';
import { extractHashtags } from '@/misc/extract-hashtags.js';
import type { IMentionedRemoteUsers } from '@/models/entities/Note.js';
import { MiNote } from '@/models/entities/Note.js';
import type { ChannelsRepository, InstancesRepository, MutedNotesRepository, MutingsRepository, NotesRepository, NoteThreadMutingsRepository, UserProfilesRepository, UsersRepository } from '@/models/_.js';
import type { MiDriveFile } from '@/models/entities/DriveFile.js';
import type { MiApp } from '@/models/entities/App.js';
import type { IMentionedRemoteUsers } from '@/models/Note.js';
import { MiNote } from '@/models/Note.js';
import type { ChannelsRepository, FollowingsRepository, InstancesRepository, MutedNotesRepository, MutingsRepository, NotesRepository, NoteThreadMutingsRepository, UserProfilesRepository, UsersRepository } from '@/models/_.js';
import type { MiDriveFile } from '@/models/DriveFile.js';
import type { MiApp } from '@/models/App.js';
import { concat } from '@/misc/prelude/array.js';
import { IdService } from '@/core/IdService.js';
import type { MiUser, MiLocalUser, MiRemoteUser } from '@/models/entities/User.js';
import type { IPoll } from '@/models/entities/Poll.js';
import { MiPoll } from '@/models/entities/Poll.js';
import type { MiUser, MiLocalUser, MiRemoteUser } from '@/models/User.js';
import type { IPoll } from '@/models/Poll.js';
import { MiPoll } from '@/models/Poll.js';
import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error.js';
import { checkWordMute } from '@/misc/check-word-mute.js';
import type { MiChannel } from '@/models/entities/Channel.js';
import type { MiChannel } from '@/models/Channel.js';
import { normalizeForSearch } from '@/misc/normalize-for-search.js';
import { MemorySingleCache } from '@/misc/cache.js';
import type { MiUserProfile } from '@/models/entities/UserProfile.js';
import type { MiUserProfile } from '@/models/UserProfile.js';
import { RelayService } from '@/core/RelayService.js';
import { FederatedInstanceService } from '@/core/FederatedInstanceService.js';
import { DI } from '@/di-symbols.js';
@@ -185,6 +185,9 @@ export class NoteCreateService implements OnApplicationShutdown {
@Inject(DI.noteThreadMutingsRepository)
private noteThreadMutingsRepository: NoteThreadMutingsRepository,
@Inject(DI.followingsRepository)
private followingsRepository: FollowingsRepository,
private userEntityService: UserEntityService,
private noteEntityService: NoteEntityService,
private idService: IdService,
@@ -505,6 +508,20 @@ export class NoteCreateService implements OnApplicationShutdown {
this.saveReply(data.reply, note);
}
if (data.reply == null) {
this.followingsRepository.findBy({
followeeId: user.id,
notify: 'normal',
}).then(followings => {
for (const following of followings) {
this.notificationService.createNotification(following.followerId, 'note', {
notifierId: user.id,
noteId: note.id,
});
}
});
}
// この投稿を除く指定したユーザーによる指定したノートのリノートが存在しないとき
if (data.renote && (await this.noteEntityService.countSameRenotes(user.id, data.renote.id, note.id) === 0)) {
if (!user.isBot) this.incRenoteCount(data.renote);

View File

@@ -5,8 +5,8 @@
import { Brackets, In } from 'typeorm';
import { Injectable, Inject } from '@nestjs/common';
import type { MiUser, MiLocalUser, MiRemoteUser } from '@/models/entities/User.js';
import type { MiNote, IMentionedRemoteUsers } from '@/models/entities/Note.js';
import type { MiUser, MiLocalUser, MiRemoteUser } from '@/models/User.js';
import type { MiNote, IMentionedRemoteUsers } from '@/models/Note.js';
import type { InstancesRepository, NotesRepository, UsersRepository } from '@/models/_.js';
import { RelayService } from '@/core/RelayService.js';
import { FederatedInstanceService } from '@/core/FederatedInstanceService.js';

View File

@@ -7,10 +7,10 @@ import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { NotesRepository, UserNotePiningsRepository, UsersRepository } from '@/models/_.js';
import { IdentifiableError } from '@/misc/identifiable-error.js';
import type { MiUser } from '@/models/entities/User.js';
import type { MiNote } from '@/models/entities/Note.js';
import type { MiUser } from '@/models/User.js';
import type { MiNote } from '@/models/Note.js';
import { IdService } from '@/core/IdService.js';
import type { MiUserNotePining } from '@/models/entities/UserNotePining.js';
import type { MiUserNotePining } from '@/models/UserNotePining.js';
import { RelayService } from '@/core/RelayService.js';
import type { Config } from '@/config.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';

View File

@@ -7,9 +7,9 @@ import { setTimeout } from 'node:timers/promises';
import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';
import { In } from 'typeorm';
import { DI } from '@/di-symbols.js';
import type { MiUser } from '@/models/entities/User.js';
import type { MiUser } from '@/models/User.js';
import type { Packed } from '@/misc/json-schema.js';
import type { MiNote } from '@/models/entities/Note.js';
import type { MiNote } from '@/models/Note.js';
import { IdService } from '@/core/IdService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import type { NoteUnreadsRepository, MutingsRepository, NoteThreadMutingsRepository } from '@/models/_.js';

View File

@@ -9,8 +9,8 @@ import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';
import { In } from 'typeorm';
import { DI } from '@/di-symbols.js';
import type { UsersRepository } from '@/models/_.js';
import type { MiUser } from '@/models/entities/User.js';
import type { MiNotification } from '@/models/entities/Notification.js';
import type { MiUser } from '@/models/User.js';
import type { MiNotification } from '@/models/Notification.js';
import { bindThis } from '@/decorators.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import { PushNotificationService } from '@/core/PushNotificationService.js';

View File

@@ -6,7 +6,7 @@
import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { NotesRepository, UsersRepository, PollsRepository, PollVotesRepository, MiUser } from '@/models/_.js';
import type { MiNote } from '@/models/entities/Note.js';
import type { MiNote } from '@/models/Note.js';
import { RelayService } from '@/core/RelayService.js';
import { IdService } from '@/core/IdService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';

View File

@@ -5,7 +5,7 @@
import { Inject, Injectable } from '@nestjs/common';
import type { UsersRepository } from '@/models/_.js';
import type { MiLocalUser } from '@/models/entities/User.js';
import type { MiLocalUser } from '@/models/User.js';
import { DI } from '@/di-symbols.js';
import { MetaService } from '@/core/MetaService.js';
import { bindThis } from '@/decorators.js';

View File

@@ -6,7 +6,7 @@
import { Inject, Injectable } from '@nestjs/common';
import { Brackets, ObjectLiteral } from 'typeorm';
import { DI } from '@/di-symbols.js';
import type { MiUser } from '@/models/entities/User.js';
import type { MiUser } from '@/models/User.js';
import type { UserProfilesRepository, FollowingsRepository, ChannelFollowingsRepository, MutedNotesRepository, BlockingsRepository, NoteThreadMutingsRepository, MutingsRepository, RenoteMutingsRepository } from '@/models/_.js';
import { bindThis } from '@/decorators.js';
import type { SelectQueryBuilder } from 'typeorm';

View File

@@ -6,8 +6,8 @@
import { randomUUID } from 'node:crypto';
import { Inject, Injectable } from '@nestjs/common';
import type { IActivity } from '@/core/activitypub/type.js';
import type { MiDriveFile } from '@/models/entities/DriveFile.js';
import type { MiWebhook, webhookEventTypes } from '@/models/entities/Webhook.js';
import type { MiDriveFile } from '@/models/DriveFile.js';
import type { MiWebhook, webhookEventTypes } from '@/models/Webhook.js';
import type { Config } from '@/config.js';
import { DI } from '@/di-symbols.js';
import { bindThis } from '@/decorators.js';

View File

@@ -7,10 +7,10 @@ import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { EmojisRepository, NoteReactionsRepository, UsersRepository, NotesRepository } from '@/models/_.js';
import { IdentifiableError } from '@/misc/identifiable-error.js';
import type { MiRemoteUser, MiUser } from '@/models/entities/User.js';
import type { MiNote } from '@/models/entities/Note.js';
import type { MiRemoteUser, MiUser } from '@/models/User.js';
import type { MiNote } from '@/models/Note.js';
import { IdService } from '@/core/IdService.js';
import type { MiNoteReaction } from '@/models/entities/NoteReaction.js';
import type { MiNoteReaction } from '@/models/NoteReaction.js';
import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import { NotificationService } from '@/core/NotificationService.js';

View File

@@ -5,11 +5,11 @@
import { Inject, Injectable } from '@nestjs/common';
import { IsNull } from 'typeorm';
import type { MiLocalUser, MiUser } from '@/models/entities/User.js';
import type { MiLocalUser, MiUser } from '@/models/User.js';
import type { RelaysRepository, UsersRepository } from '@/models/_.js';
import { IdService } from '@/core/IdService.js';
import { MemorySingleCache } from '@/misc/cache.js';
import type { MiRelay } from '@/models/entities/Relay.js';
import type { MiRelay } from '@/models/Relay.js';
import { QueueService } from '@/core/QueueService.js';
import { CreateSystemUserService } from '@/core/CreateSystemUserService.js';
import { ApRendererService } from '@/core/activitypub/ApRendererService.js';

View File

@@ -9,7 +9,7 @@ import chalk from 'chalk';
import { IsNull } from 'typeorm';
import { DI } from '@/di-symbols.js';
import type { UsersRepository } from '@/models/_.js';
import type { MiLocalUser, MiRemoteUser } from '@/models/entities/User.js';
import type { MiLocalUser, MiRemoteUser } from '@/models/User.js';
import type { Config } from '@/config.js';
import type Logger from '@/logger.js';
import { UtilityService } from '@/core/UtilityService.js';

View File

@@ -8,12 +8,12 @@ import * as Redis from 'ioredis';
import { In } from 'typeorm';
import type { MiRole, MiRoleAssignment, RoleAssignmentsRepository, RolesRepository, UsersRepository } from '@/models/_.js';
import { MemoryKVCache, MemorySingleCache } from '@/misc/cache.js';
import type { MiUser } from '@/models/entities/User.js';
import type { MiUser } from '@/models/User.js';
import { DI } from '@/di-symbols.js';
import { bindThis } from '@/decorators.js';
import { MetaService } from '@/core/MetaService.js';
import { CacheService } from '@/core/CacheService.js';
import type { RoleCondFormulaValue } from '@/models/entities/Role.js';
import type { RoleCondFormulaValue } from '@/models/Role.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { StreamMessages } from '@/server/api/stream/types.js';
import { IdService } from '@/core/IdService.js';

View File

@@ -10,7 +10,7 @@ import { Injectable } from '@nestjs/common';
import { DeleteObjectCommand, S3Client } from '@aws-sdk/client-s3';
import { Upload } from '@aws-sdk/lib-storage';
import { NodeHttpHandler, NodeHttpHandlerOptions } from '@smithy/node-http-handler';
import type { MiMeta } from '@/models/entities/Meta.js';
import type { MiMeta } from '@/models/Meta.js';
import { HttpRequestService } from '@/core/HttpRequestService.js';
import { bindThis } from '@/decorators.js';
import type { DeleteObjectCommandInput, PutObjectCommandInput } from '@aws-sdk/client-s3';

View File

@@ -8,7 +8,7 @@ import { In } from 'typeorm';
import { DI } from '@/di-symbols.js';
import type { Config } from '@/config.js';
import { bindThis } from '@/decorators.js';
import { MiNote } from '@/models/entities/Note.js';
import { MiNote } from '@/models/Note.js';
import { MiUser } from '@/models/_.js';
import type { NotesRepository } from '@/models/_.js';
import { sqlLikeEscape } from '@/misc/sql-like-escape.js';

View File

@@ -9,11 +9,11 @@ import bcrypt from 'bcryptjs';
import { DataSource, IsNull } from 'typeorm';
import { DI } from '@/di-symbols.js';
import type { UsedUsernamesRepository, UsersRepository } from '@/models/_.js';
import { MiUser } from '@/models/entities/User.js';
import { MiUserProfile } from '@/models/entities/UserProfile.js';
import { MiUser } from '@/models/User.js';
import { MiUserProfile } from '@/models/UserProfile.js';
import { IdService } from '@/core/IdService.js';
import { MiUserKeypair } from '@/models/entities/UserKeypair.js';
import { MiUsedUsername } from '@/models/entities/UsedUsername.js';
import { MiUserKeypair } from '@/models/UserKeypair.js';
import { MiUsedUsername } from '@/models/UsedUsername.js';
import generateUserToken from '@/misc/generate-native-user-token.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { bindThis } from '@/decorators.js';

View File

@@ -0,0 +1,45 @@
/*
* SPDX-FileCopyrightText: syuilo and other misskey contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { Inject, Injectable } from '@nestjs/common';
import { QueryFailedError } from 'typeorm';
import * as OTPAuth from 'otpauth';
import { DI } from '@/di-symbols.js';
import type { MiUserProfile, UserProfilesRepository, UsersRepository } from '@/models/_.js';
import { bindThis } from '@/decorators.js';
import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error.js';
import type { MiLocalUser } from '@/models/User.js';
@Injectable()
export class UserAuthService {
constructor(
@Inject(DI.usersRepository)
private usersRepository: UsersRepository,
@Inject(DI.userProfilesRepository)
private userProfilesRepository: UserProfilesRepository,
) {
}
@bindThis
public async twoFactorAuthenticate(profile: MiUserProfile, token: string): Promise<void> {
if (profile.twoFactorBackupSecret?.includes(token)) {
await this.userProfilesRepository.update({ userId: profile.userId }, {
twoFactorBackupSecret: profile.twoFactorBackupSecret.filter((secret) => secret !== token),
});
} else {
const delta = OTPAuth.TOTP.validate({
secret: OTPAuth.Secret.fromBase32(profile.twoFactorSecret!),
digits: 6,
token,
window: 5,
});
if (delta === null) {
throw new Error('authentication failed');
}
}
}
}

View File

@@ -6,8 +6,8 @@
import { Inject, Injectable, OnModuleInit } from '@nestjs/common';
import { ModuleRef } from '@nestjs/core';
import { IdService } from '@/core/IdService.js';
import type { MiUser } from '@/models/entities/User.js';
import type { MiBlocking } from '@/models/entities/Blocking.js';
import type { MiUser } from '@/models/User.js';
import type { MiBlocking } from '@/models/Blocking.js';
import { QueueService } from '@/core/QueueService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import { DI } from '@/di-symbols.js';

View File

@@ -6,7 +6,7 @@
import { Inject, Injectable, OnModuleInit, forwardRef } from '@nestjs/common';
import { ModuleRef } from '@nestjs/core';
import { IsNull } from 'typeorm';
import type { MiLocalUser, MiPartialLocalUser, MiPartialRemoteUser, MiRemoteUser, MiUser } from '@/models/entities/User.js';
import type { MiLocalUser, MiPartialLocalUser, MiPartialRemoteUser, MiRemoteUser, MiUser } from '@/models/User.js';
import { IdentifiableError } from '@/misc/identifiable-error.js';
import { QueueService } from '@/core/QueueService.js';
import PerUserFollowingChart from '@/core/chart/charts/per-user-following.js';

View File

@@ -5,10 +5,10 @@
import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';
import * as Redis from 'ioredis';
import type { MiUser } from '@/models/entities/User.js';
import type { MiUser } from '@/models/User.js';
import type { UserKeypairsRepository } from '@/models/_.js';
import { RedisKVCache } from '@/misc/cache.js';
import type { MiUserKeypair } from '@/models/entities/UserKeypair.js';
import type { MiUserKeypair } from '@/models/UserKeypair.js';
import { DI } from '@/di-symbols.js';
import { bindThis } from '@/decorators.js';

View File

@@ -5,9 +5,9 @@
import { Inject, Injectable } from '@nestjs/common';
import type { UserListJoiningsRepository } from '@/models/_.js';
import type { MiUser } from '@/models/entities/User.js';
import type { MiUserList } from '@/models/entities/UserList.js';
import type { MiUserListJoining } from '@/models/entities/UserListJoining.js';
import type { MiUser } from '@/models/User.js';
import type { MiUserList } from '@/models/UserList.js';
import type { MiUserListJoining } from '@/models/UserListJoining.js';
import { IdService } from '@/core/IdService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import { DI } from '@/di-symbols.js';

View File

@@ -7,7 +7,7 @@ import { Inject, Injectable } from '@nestjs/common';
import { In } from 'typeorm';
import type { MutingsRepository, MiMuting } from '@/models/_.js';
import { IdService } from '@/core/IdService.js';
import type { MiUser } from '@/models/entities/User.js';
import type { MiUser } from '@/models/User.js';
import { DI } from '@/di-symbols.js';
import { bindThis } from '@/decorators.js';
import { CacheService } from '@/core/CacheService.js';

View File

@@ -6,7 +6,7 @@
import { Inject, Injectable } from '@nestjs/common';
import { Not, IsNull } from 'typeorm';
import type { FollowingsRepository } from '@/models/_.js';
import type { MiUser } from '@/models/entities/User.js';
import type { MiUser } from '@/models/User.js';
import { QueueService } from '@/core/QueueService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import { DI } from '@/di-symbols.js';

View File

@@ -6,7 +6,7 @@
import { Inject, Injectable } from '@nestjs/common';
import * as Redis from 'ioredis';
import type { WebhooksRepository } from '@/models/_.js';
import type { MiWebhook } from '@/models/entities/Webhook.js';
import type { MiWebhook } from '@/models/Webhook.js';
import { DI } from '@/di-symbols.js';
import { bindThis } from '@/decorators.js';
import { StreamMessages } from '@/server/api/stream/types.js';

View File

@@ -5,7 +5,7 @@
import { Injectable } from '@nestjs/common';
import promiseLimit from 'promise-limit';
import type { MiRemoteUser, MiUser } from '@/models/entities/User.js';
import type { MiRemoteUser, MiUser } from '@/models/User.js';
import { concat, unique } from '@/misc/prelude/array.js';
import { bindThis } from '@/decorators.js';
import { getApIds } from './type.js';

View File

@@ -8,11 +8,11 @@ import { DI } from '@/di-symbols.js';
import type { NotesRepository, UserPublickeysRepository, UsersRepository } from '@/models/_.js';
import type { Config } from '@/config.js';
import { MemoryKVCache } from '@/misc/cache.js';
import type { MiUserPublickey } from '@/models/entities/UserPublickey.js';
import type { MiUserPublickey } from '@/models/UserPublickey.js';
import { CacheService } from '@/core/CacheService.js';
import type { MiNote } from '@/models/entities/Note.js';
import type { MiNote } from '@/models/Note.js';
import { bindThis } from '@/decorators.js';
import { MiLocalUser, MiRemoteUser } from '@/models/entities/User.js';
import { MiLocalUser, MiRemoteUser } from '@/models/User.js';
import { getApId } from './type.js';
import { ApPersonService } from './models/ApPersonService.js';
import type { IObject } from './type.js';

View File

@@ -7,7 +7,7 @@ import { Inject, Injectable } from '@nestjs/common';
import { IsNull, Not } from 'typeorm';
import { DI } from '@/di-symbols.js';
import type { FollowingsRepository } from '@/models/_.js';
import type { MiLocalUser, MiRemoteUser, MiUser } from '@/models/entities/User.js';
import type { MiLocalUser, MiRemoteUser, MiUser } from '@/models/User.js';
import { QueueService } from '@/core/QueueService.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { bindThis } from '@/decorators.js';

View File

@@ -26,7 +26,7 @@ import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { QueueService } from '@/core/QueueService.js';
import type { UsersRepository, NotesRepository, FollowingsRepository, AbuseUserReportsRepository, FollowRequestsRepository } from '@/models/_.js';
import { bindThis } from '@/decorators.js';
import type { MiRemoteUser } from '@/models/entities/User.js';
import type { MiRemoteUser } from '@/models/User.js';
import { getApHrefNullable, getApId, getApIds, getApType, isAccept, isActor, isAdd, isAnnounce, isBlock, isCollection, isCollectionOrOrderedCollection, isCreate, isDelete, isFlag, isFollow, isLike, isMove, isPost, isReject, isRemove, isTombstone, isUndo, isUpdate, validActor, validPost } from './type.js';
import { ApNoteService } from './models/ApNoteService.js';
import { ApLoggerService } from './ApLoggerService.js';

View File

@@ -6,7 +6,7 @@
import { Injectable } from '@nestjs/common';
import * as mfm from 'mfm-js';
import { MfmService } from '@/core/MfmService.js';
import type { MiNote } from '@/models/entities/Note.js';
import type { MiNote } from '@/models/Note.js';
import { bindThis } from '@/decorators.js';
import { extractApHashtagObjects } from './models/tag.js';
import type { IObject } from './type.js';

View File

@@ -9,20 +9,20 @@ import { In } from 'typeorm';
import * as mfm from 'mfm-js';
import { DI } from '@/di-symbols.js';
import type { Config } from '@/config.js';
import type { MiPartialLocalUser, MiLocalUser, MiPartialRemoteUser, MiRemoteUser, MiUser } from '@/models/entities/User.js';
import type { IMentionedRemoteUsers, MiNote } from '@/models/entities/Note.js';
import type { MiBlocking } from '@/models/entities/Blocking.js';
import type { MiRelay } from '@/models/entities/Relay.js';
import type { MiDriveFile } from '@/models/entities/DriveFile.js';
import type { MiNoteReaction } from '@/models/entities/NoteReaction.js';
import type { MiEmoji } from '@/models/entities/Emoji.js';
import type { MiPoll } from '@/models/entities/Poll.js';
import type { MiPollVote } from '@/models/entities/PollVote.js';
import type { MiPartialLocalUser, MiLocalUser, MiPartialRemoteUser, MiRemoteUser, MiUser } from '@/models/User.js';
import type { IMentionedRemoteUsers, MiNote } from '@/models/Note.js';
import type { MiBlocking } from '@/models/Blocking.js';
import type { MiRelay } from '@/models/Relay.js';
import type { MiDriveFile } from '@/models/DriveFile.js';
import type { MiNoteReaction } from '@/models/NoteReaction.js';
import type { MiEmoji } from '@/models/Emoji.js';
import type { MiPoll } from '@/models/Poll.js';
import type { MiPollVote } from '@/models/PollVote.js';
import { UserKeypairService } from '@/core/UserKeypairService.js';
import { MfmService } from '@/core/MfmService.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js';
import type { MiUserKeypair } from '@/models/entities/UserKeypair.js';
import type { MiUserKeypair } from '@/models/UserKeypair.js';
import type { UsersRepository, UserProfilesRepository, NotesRepository, DriveFilesRepository, PollsRepository } from '@/models/_.js';
import { bindThis } from '@/decorators.js';
import { CustomEmojiService } from '@/core/CustomEmojiService.js';

View File

@@ -8,7 +8,7 @@ import { URL } from 'node:url';
import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { Config } from '@/config.js';
import type { MiUser } from '@/models/entities/User.js';
import type { MiUser } from '@/models/User.js';
import { UserKeypairService } from '@/core/UserKeypairService.js';
import { HttpRequestService } from '@/core/HttpRequestService.js';
import { LoggerService } from '@/core/LoggerService.js';

View File

@@ -4,9 +4,10 @@
*/
import { Inject, Injectable } from '@nestjs/common';
import type { MiLocalUser, MiRemoteUser } from '@/models/entities/User.js';
import { IsNull, Not } from 'typeorm';
import type { MiLocalUser, MiRemoteUser } from '@/models/User.js';
import { InstanceActorService } from '@/core/InstanceActorService.js';
import type { NotesRepository, PollsRepository, NoteReactionsRepository, UsersRepository } from '@/models/_.js';
import type { NotesRepository, PollsRepository, NoteReactionsRepository, UsersRepository, FollowRequestsRepository } from '@/models/_.js';
import type { Config } from '@/config.js';
import { MetaService } from '@/core/MetaService.js';
import { HttpRequestService } from '@/core/HttpRequestService.js';
@@ -32,6 +33,7 @@ export class Resolver {
private notesRepository: NotesRepository,
private pollsRepository: PollsRepository,
private noteReactionsRepository: NoteReactionsRepository,
private followRequestsRepository: FollowRequestsRepository,
private utilityService: UtilityService,
private instanceActorService: InstanceActorService,
private metaService: MetaService,
@@ -146,13 +148,24 @@ export class Resolver {
return this.noteReactionsRepository.findOneByOrFail({ id: parsed.id }).then(async reaction =>
this.apRendererService.addContext(await this.apRendererService.renderLike(reaction, { uri: null })));
case 'follows':
// rest should be <followee id>
if (parsed.rest == null || !/^\w+$/.test(parsed.rest)) throw new Error('resolveLocal: invalid follow URI');
return Promise.all(
[parsed.id, parsed.rest].map(id => this.usersRepository.findOneByOrFail({ id })),
)
.then(([follower, followee]) => this.apRendererService.addContext(this.apRendererService.renderFollow(follower as MiLocalUser | MiRemoteUser, followee as MiLocalUser | MiRemoteUser, url)));
return this.followRequestsRepository.findOneBy({ id: parsed.id })
.then(async followRequest => {
if (followRequest == null) throw new Error('resolveLocal: invalid follow request ID');
const [follower, followee] = await Promise.all([
this.usersRepository.findOneBy({
id: followRequest.followerId,
host: IsNull(),
}),
this.usersRepository.findOneBy({
id: followRequest.followeeId,
host: Not(IsNull()),
}),
]);
if (follower == null || followee == null) {
throw new Error('resolveLocal: follower or followee does not exist');
}
return this.apRendererService.addContext(this.apRendererService.renderFollow(follower as MiLocalUser | MiRemoteUser, followee as MiLocalUser | MiRemoteUser, url));
});
default:
throw new Error(`resolveLocal: type ${parsed.type} unhandled`);
}
@@ -177,6 +190,9 @@ export class ApResolverService {
@Inject(DI.noteReactionsRepository)
private noteReactionsRepository: NoteReactionsRepository,
@Inject(DI.followRequestsRepository)
private followRequestsRepository: FollowRequestsRepository,
private utilityService: UtilityService,
private instanceActorService: InstanceActorService,
private metaService: MetaService,
@@ -196,6 +212,7 @@ export class ApResolverService {
this.notesRepository,
this.pollsRepository,
this.noteReactionsRepository,
this.followRequestsRepository,
this.utilityService,
this.instanceActorService,
this.metaService,

View File

@@ -6,8 +6,8 @@
import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { DriveFilesRepository } from '@/models/_.js';
import type { MiRemoteUser } from '@/models/entities/User.js';
import type { MiDriveFile } from '@/models/entities/DriveFile.js';
import type { MiRemoteUser } from '@/models/User.js';
import type { MiDriveFile } from '@/models/DriveFile.js';
import { MetaService } from '@/core/MetaService.js';
import { truncate } from '@/misc/truncate.js';
import { DB_MAX_IMAGE_COMMENT_LENGTH } from '@/const.js';

View File

@@ -9,13 +9,13 @@ import { In } from 'typeorm';
import { DI } from '@/di-symbols.js';
import type { PollsRepository, EmojisRepository } from '@/models/_.js';
import type { Config } from '@/config.js';
import type { MiRemoteUser } from '@/models/entities/User.js';
import type { MiNote } from '@/models/entities/Note.js';
import type { MiRemoteUser } from '@/models/User.js';
import type { MiNote } from '@/models/Note.js';
import { toArray, toSingle, unique } from '@/misc/prelude/array.js';
import type { MiEmoji } from '@/models/entities/Emoji.js';
import type { MiEmoji } from '@/models/Emoji.js';
import { MetaService } from '@/core/MetaService.js';
import { AppLockService } from '@/core/AppLockService.js';
import type { MiDriveFile } from '@/models/entities/DriveFile.js';
import type { MiDriveFile } from '@/models/DriveFile.js';
import { NoteCreateService } from '@/core/NoteCreateService.js';
import type Logger from '@/logger.js';
import { IdService } from '@/core/IdService.js';

View File

@@ -10,26 +10,26 @@ import { ModuleRef } from '@nestjs/core';
import { DI } from '@/di-symbols.js';
import type { FollowingsRepository, InstancesRepository, UserProfilesRepository, UserPublickeysRepository, UsersRepository } from '@/models/_.js';
import type { Config } from '@/config.js';
import type { MiLocalUser, MiRemoteUser } from '@/models/entities/User.js';
import { MiUser } from '@/models/entities/User.js';
import type { MiLocalUser, MiRemoteUser } from '@/models/User.js';
import { MiUser } from '@/models/User.js';
import { truncate } from '@/misc/truncate.js';
import type { CacheService } from '@/core/CacheService.js';
import { normalizeForSearch } from '@/misc/normalize-for-search.js';
import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error.js';
import type Logger from '@/logger.js';
import type { MiNote } from '@/models/entities/Note.js';
import type { MiNote } from '@/models/Note.js';
import type { IdService } from '@/core/IdService.js';
import type { MfmService } from '@/core/MfmService.js';
import { toArray } from '@/misc/prelude/array.js';
import type { GlobalEventService } from '@/core/GlobalEventService.js';
import type { FederatedInstanceService } from '@/core/FederatedInstanceService.js';
import type { FetchInstanceMetadataService } from '@/core/FetchInstanceMetadataService.js';
import { MiUserProfile } from '@/models/entities/UserProfile.js';
import { MiUserPublickey } from '@/models/entities/UserPublickey.js';
import { MiUserProfile } from '@/models/UserProfile.js';
import { MiUserPublickey } from '@/models/UserPublickey.js';
import type UsersChart from '@/core/chart/charts/users.js';
import type InstanceChart from '@/core/chart/charts/instance.js';
import type { HashtagService } from '@/core/HashtagService.js';
import { MiUserNotePining } from '@/models/entities/UserNotePining.js';
import { MiUserNotePining } from '@/models/UserNotePining.js';
import { StatusError } from '@/misc/status-error.js';
import type { UtilityService } from '@/core/UtilityService.js';
import type { UserEntityService } from '@/core/entities/UserEntityService.js';

View File

@@ -7,7 +7,7 @@ import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { NotesRepository, PollsRepository } from '@/models/_.js';
import type { Config } from '@/config.js';
import type { IPoll } from '@/models/entities/Poll.js';
import type { IPoll } from '@/models/Poll.js';
import type Logger from '@/logger.js';
import { bindThis } from '@/decorators.js';
import { isQuestion } from '../type.js';

View File

@@ -6,7 +6,7 @@
import { Injectable, Inject } from '@nestjs/common';
import { DataSource } from 'typeorm';
import { AppLockService } from '@/core/AppLockService.js';
import type { MiUser } from '@/models/entities/User.js';
import type { MiUser } from '@/models/User.js';
import { DI } from '@/di-symbols.js';
import { bindThis } from '@/decorators.js';
import Chart from '../core.js';

View File

@@ -5,7 +5,7 @@
import { Injectable, Inject } from '@nestjs/common';
import { DataSource } from 'typeorm';
import type { MiDriveFile } from '@/models/entities/DriveFile.js';
import type { MiDriveFile } from '@/models/DriveFile.js';
import { AppLockService } from '@/core/AppLockService.js';
import { DI } from '@/di-symbols.js';
import { bindThis } from '@/decorators.js';

View File

@@ -6,8 +6,8 @@
import { Injectable, Inject } from '@nestjs/common';
import { DataSource } from 'typeorm';
import type { DriveFilesRepository, FollowingsRepository, UsersRepository, NotesRepository } from '@/models/_.js';
import type { MiDriveFile } from '@/models/entities/DriveFile.js';
import type { MiNote } from '@/models/entities/Note.js';
import type { MiDriveFile } from '@/models/DriveFile.js';
import type { MiNote } from '@/models/Note.js';
import { AppLockService } from '@/core/AppLockService.js';
import { DI } from '@/di-symbols.js';
import { UtilityService } from '@/core/UtilityService.js';

View File

@@ -6,7 +6,7 @@
import { Injectable, Inject } from '@nestjs/common';
import { Not, IsNull, DataSource } from 'typeorm';
import type { NotesRepository } from '@/models/_.js';
import type { MiNote } from '@/models/entities/Note.js';
import type { MiNote } from '@/models/Note.js';
import { AppLockService } from '@/core/AppLockService.js';
import { DI } from '@/di-symbols.js';
import { bindThis } from '@/decorators.js';

View File

@@ -6,7 +6,7 @@
import { Injectable, Inject } from '@nestjs/common';
import { DataSource } from 'typeorm';
import type { DriveFilesRepository } from '@/models/_.js';
import type { MiDriveFile } from '@/models/entities/DriveFile.js';
import type { MiDriveFile } from '@/models/DriveFile.js';
import { AppLockService } from '@/core/AppLockService.js';
import { DI } from '@/di-symbols.js';
import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js';

View File

@@ -5,7 +5,7 @@
import { Injectable, Inject } from '@nestjs/common';
import { Not, IsNull, DataSource } from 'typeorm';
import type { MiUser } from '@/models/entities/User.js';
import type { MiUser } from '@/models/User.js';
import { AppLockService } from '@/core/AppLockService.js';
import { DI } from '@/di-symbols.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';

View File

@@ -5,8 +5,8 @@
import { Injectable, Inject } from '@nestjs/common';
import { DataSource } from 'typeorm';
import type { MiUser } from '@/models/entities/User.js';
import type { MiNote } from '@/models/entities/Note.js';
import type { MiUser } from '@/models/User.js';
import type { MiNote } from '@/models/Note.js';
import { AppLockService } from '@/core/AppLockService.js';
import { DI } from '@/di-symbols.js';
import type { NotesRepository } from '@/models/_.js';

View File

@@ -5,7 +5,7 @@
import { Injectable, Inject } from '@nestjs/common';
import { DataSource } from 'typeorm';
import type { MiUser } from '@/models/entities/User.js';
import type { MiUser } from '@/models/User.js';
import { AppLockService } from '@/core/AppLockService.js';
import { DI } from '@/di-symbols.js';
import { bindThis } from '@/decorators.js';

View File

@@ -5,8 +5,8 @@
import { Injectable, Inject } from '@nestjs/common';
import { DataSource } from 'typeorm';
import type { MiUser } from '@/models/entities/User.js';
import type { MiNote } from '@/models/entities/Note.js';
import type { MiUser } from '@/models/User.js';
import type { MiNote } from '@/models/Note.js';
import { AppLockService } from '@/core/AppLockService.js';
import { DI } from '@/di-symbols.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';

View File

@@ -5,7 +5,7 @@
import { Injectable, Inject } from '@nestjs/common';
import { Not, IsNull, DataSource } from 'typeorm';
import type { MiUser } from '@/models/entities/User.js';
import type { MiUser } from '@/models/User.js';
import { AppLockService } from '@/core/AppLockService.js';
import { DI } from '@/di-symbols.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';

View File

@@ -7,7 +7,7 @@ import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { AbuseUserReportsRepository } from '@/models/_.js';
import { awaitAll } from '@/misc/prelude/await-all.js';
import type { MiAbuseUserReport } from '@/models/entities/AbuseUserReport.js';
import type { MiAbuseUserReport } from '@/models/AbuseUserReport.js';
import { bindThis } from '@/decorators.js';
import { UserEntityService } from './UserEntityService.js';

View File

@@ -7,7 +7,7 @@ import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { AntennasRepository } from '@/models/_.js';
import type { Packed } from '@/misc/json-schema.js';
import type { MiAntenna } from '@/models/entities/Antenna.js';
import type { MiAntenna } from '@/models/Antenna.js';
import { bindThis } from '@/decorators.js';
@Injectable()

View File

@@ -7,8 +7,8 @@ import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { AccessTokensRepository, AppsRepository } from '@/models/_.js';
import type { Packed } from '@/misc/json-schema.js';
import type { MiApp } from '@/models/entities/App.js';
import type { MiUser } from '@/models/entities/User.js';
import type { MiApp } from '@/models/App.js';
import type { MiUser } from '@/models/User.js';
import { bindThis } from '@/decorators.js';
@Injectable()

View File

@@ -7,8 +7,8 @@ import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { AuthSessionsRepository } from '@/models/_.js';
import { awaitAll } from '@/misc/prelude/await-all.js';
import type { MiAuthSession } from '@/models/entities/AuthSession.js';
import type { MiUser } from '@/models/entities/User.js';
import type { MiAuthSession } from '@/models/AuthSession.js';
import type { MiUser } from '@/models/User.js';
import { bindThis } from '@/decorators.js';
import { AppEntityService } from './AppEntityService.js';

View File

@@ -8,8 +8,8 @@ import { DI } from '@/di-symbols.js';
import type { BlockingsRepository } from '@/models/_.js';
import { awaitAll } from '@/misc/prelude/await-all.js';
import type { Packed } from '@/misc/json-schema.js';
import type { MiBlocking } from '@/models/entities/Blocking.js';
import type { MiUser } from '@/models/entities/User.js';
import type { MiBlocking } from '@/models/Blocking.js';
import type { MiUser } from '@/models/User.js';
import { bindThis } from '@/decorators.js';
import { UserEntityService } from './UserEntityService.js';

View File

@@ -7,9 +7,9 @@ import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { ChannelFavoritesRepository, ChannelFollowingsRepository, ChannelsRepository, DriveFilesRepository, NoteUnreadsRepository, NotesRepository } from '@/models/_.js';
import type { Packed } from '@/misc/json-schema.js';
import type { } from '@/models/entities/Blocking.js';
import type { MiUser } from '@/models/entities/User.js';
import type { MiChannel } from '@/models/entities/Channel.js';
import type { } from '@/models/Blocking.js';
import type { MiUser } from '@/models/User.js';
import type { MiChannel } from '@/models/Channel.js';
import { bindThis } from '@/decorators.js';
import { DriveFileEntityService } from './DriveFileEntityService.js';
import { NoteEntityService } from './NoteEntityService.js';

View File

@@ -8,8 +8,8 @@ import { DI } from '@/di-symbols.js';
import type { ClipFavoritesRepository, ClipsRepository, MiUser } from '@/models/_.js';
import { awaitAll } from '@/misc/prelude/await-all.js';
import type { Packed } from '@/misc/json-schema.js';
import type { } from '@/models/entities/Blocking.js';
import type { MiClip } from '@/models/entities/Clip.js';
import type { } from '@/models/Blocking.js';
import type { MiClip } from '@/models/Clip.js';
import { bindThis } from '@/decorators.js';
import { UserEntityService } from './UserEntityService.js';

View File

@@ -10,8 +10,8 @@ import type { DriveFilesRepository } from '@/models/_.js';
import type { Config } from '@/config.js';
import type { Packed } from '@/misc/json-schema.js';
import { awaitAll } from '@/misc/prelude/await-all.js';
import type { MiUser } from '@/models/entities/User.js';
import type { MiDriveFile } from '@/models/entities/DriveFile.js';
import type { MiUser } from '@/models/User.js';
import type { MiDriveFile } from '@/models/DriveFile.js';
import { appendQuery, query } from '@/misc/prelude/url.js';
import { deepClone } from '@/misc/clone.js';
import { bindThis } from '@/decorators.js';

View File

@@ -8,8 +8,8 @@ import { DI } from '@/di-symbols.js';
import type { DriveFilesRepository, DriveFoldersRepository } from '@/models/_.js';
import { awaitAll } from '@/misc/prelude/await-all.js';
import type { Packed } from '@/misc/json-schema.js';
import type { } from '@/models/entities/Blocking.js';
import type { MiDriveFolder } from '@/models/entities/DriveFolder.js';
import type { } from '@/models/Blocking.js';
import type { MiDriveFolder } from '@/models/DriveFolder.js';
import { bindThis } from '@/decorators.js';
@Injectable()

View File

@@ -7,8 +7,8 @@ import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { EmojisRepository } from '@/models/_.js';
import type { Packed } from '@/misc/json-schema.js';
import type { } from '@/models/entities/Blocking.js';
import type { MiEmoji } from '@/models/entities/Emoji.js';
import type { } from '@/models/Blocking.js';
import type { MiEmoji } from '@/models/Emoji.js';
import { bindThis } from '@/decorators.js';
@Injectable()

Some files were not shown because too many files have changed in this diff Show More