diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 5955f6b5d9..c5755315fc 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -17,16 +17,32 @@ updates: directory: "/" schedule: interval: daily - # PNPM has an issue with dependabot. See: - # https://github.com/dependabot/dependabot-core/issues/7258 - # https://github.com/pnpm/pnpm/issues/6530 - # TODO: Restore this when the issue is solved - open-pull-requests-limit: 0 + open-pull-requests-limit: 5 + # List dependencies required to be updated together, sharing the same version numbers. + # Those who simply have the common owner (e.g. @fastify) don't need to be listed. groups: - swc: + aws-sdk: patterns: - - "@swc/*" + - "@aws-sdk/*" + bull-board: + patterns: + - "@bull-board/*" + nestjs: + patterns: + - "@nestjs/*" + slacc: + patterns: + - "slacc-*" storybook: patterns: - "storybook*" - "@storybook/*" + swc-core: + patterns: + - "@swc/core*" + typescript-eslint: + patterns: + - "@typescript-eslint/*" + tensorflow: + patterns: + - "@tensorflow/*" diff --git a/CHANGELOG.md b/CHANGELOG.md index 199a420f7b..ea34fa9ef7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,8 +12,25 @@ --> +## 202x.x.x (Unreleased) + +### Client +- Enhance: ハッシュタグ入力時に、本文の末尾の行に何も書かれていない場合は新たにスペースを追加しないように + +## 2023.12.2 + +### General +- v2023.12.1でDockerを利用してサーバーを起動できない問題を修正 + +### Client +- Enhance: 検索画面においてEnterキー押下で検索できるように + ## 2023.12.1 +### Note +- アクセストークンの権限が再整理されたため、一部のAPIが古いAPIトークンでは動作しなくなりました。\ + 権限不足になる場合には権限を再設定して再生成してください。 + ### General - Enhance: ローカリゼーションの更新 - Fix: 自分のdirect noteがuser list timelineに追加されない diff --git a/COPYING b/COPYING index c218443d42..6a5f3ca1d5 100644 --- a/COPYING +++ b/COPYING @@ -1,5 +1,5 @@ Unless otherwise stated this repository is -Copyright © 2014-2023 syuilo and contributers +Copyright © 2014-2024 syuilo and contributors And is distributed under The GNU Affero General Public License Version 3, you should have received a copy of the license file as LICENSE. diff --git a/Dockerfile b/Dockerfile index 38aa5bc7b3..922ce4dca3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -51,6 +51,7 @@ WORKDIR /misskey COPY --link ["pnpm-lock.yaml", "pnpm-workspace.yaml", "package.json", "./"] COPY --link ["scripts", "./scripts"] COPY --link ["packages/backend/package.json", "./packages/backend/"] +COPY --link ["packages/misskey-js/package.json", "./packages/misskey-js/"] RUN --mount=type=cache,target=/root/.local/share/pnpm/store,sharing=locked \ pnpm i --frozen-lockfile --aggregate-output @@ -77,7 +78,9 @@ WORKDIR /misskey COPY --chown=misskey:misskey --from=target-builder /misskey/node_modules ./node_modules COPY --chown=misskey:misskey --from=target-builder /misskey/packages/backend/node_modules ./packages/backend/node_modules +COPY --chown=misskey:misskey --from=target-builder /misskey/packages/misskey-js/node_modules ./packages/misskey-js/node_modules COPY --chown=misskey:misskey --from=native-builder /misskey/built ./built +COPY --chown=misskey:misskey --from=native-builder /misskey/packages/misskey-js/built ./packages/misskey-js/built COPY --chown=misskey:misskey --from=native-builder /misskey/packages/backend/built ./packages/backend/built COPY --chown=misskey:misskey --from=native-builder /misskey/fluent-emojis /misskey/fluent-emojis COPY --chown=misskey:misskey . ./ diff --git a/locales/bn-BD.yml b/locales/bn-BD.yml index c659e13250..77ba3f0306 100644 --- a/locales/bn-BD.yml +++ b/locales/bn-BD.yml @@ -2,6 +2,7 @@ _lang_: "বাংলা" headlineMisskey: "নোট ব্যাবহার করে সংযুক্ত নেটওয়ার্ক" introMisskey: "স্বাগতম! মিসকি একটি ওপেন সোর্স, ডিসেন্ট্রালাইজড মাইক্রোব্লগিং পরিষেবা। \n\"নোট\" তৈরির মাধ্যমে যা ঘটছে তা সবার সাথে শেয়ার করুন 📡\n\"রিঅ্যাকশন\" গুলির মাধ্যমে যেকোনো নোট সম্পর্কে আপনার অনুভূতি ব্যাক্ত করতে পারেন 👍\nএকটি নতুন দুনিয়া ঘুরে দেখুন 🚀\n" +poweredByMisskeyDescription: "{name} হল ওপেন সোর্স প্ল্যাটফর্ম Misskey-এর সার্ভারগুলির একটি৷" monthAndDay: "{day}/{month}" search: "খুঁজুন" notifications: "বিজ্ঞপ্তি" @@ -12,12 +13,14 @@ fetchingAsApObject: "ফেডিভার্স থেকে খবর আন ok: "ঠিক" gotIt: "বুঝেছি" cancel: "বাতিল" +noThankYou: "না, ধন্যবাদ" enterUsername: "ইউজারনেম লিখুন" renotedBy: "{user} রিনোট করেছেন" noNotes: "কোন নোট নেই" noNotifications: "কোনো বিজ্ঞপ্তি নেই" instance: "ইন্সট্যান্স" settings: "সেটিংস" +notificationSettings: "বিজ্ঞপ্তির সেটিংস" basicSettings: "সাধারণ সেটিংস" otherSettings: "অন্যান্য সেটিংস" openInWindow: "নতুন উইন্ডোতে খুলা" @@ -42,12 +45,20 @@ pin: "পিন করা" unpin: "পিন সরান" copyContent: "বিষয়বস্তু কপি করুন" copyLink: "লিঙ্ক কপি করুন" +copyLinkRenote: "রিনোট লিঙ্ক কপি করুন" delete: "মুছুন" deleteAndEdit: "মুছুন এবং সম্পাদনা করুন" deleteAndEditConfirm: "আপনি কি এই নোটটি মুছে এটি সম্পাদনা করার বিষয়ে নিশ্চিত? আপনি এটির সমস্ত রিঅ্যাকশন, রিনোট এবং জবাব হারাবেন।" addToList: "লিস্ট এ যোগ করুন" +addToAntenna: "অ্যান্টেনা এ যোগ করুন" sendMessage: "একটি বার্তা পাঠান" +copyRSS: "RSS কপি করুন" copyUsername: "ব্যবহারকারীর নাম কপি করুন" +copyUserId: "ব্যবহারকারীর ID কপি করুন" +copyNoteId: "নোটের ID কপি করুন" +copyFileId: "ফাইল ID কপি করুন" +copyFolderId: "ফোল্ডার ID কপি করুন" +copyProfileUrl: "প্রোফাইল URL কপি করুন" searchUser: "ব্যবহারকারী খুঁজুন..." reply: "জবাব" loadMore: "আরও দেখুন" @@ -100,6 +111,8 @@ renoted: "রিনোট করা হয়েছে" cantRenote: "এই নোটটি রিনোট করা যাবে না।" cantReRenote: "রিনোটকে রিনোট করা যাবে না।" quote: "উদ্ধৃতি" +inChannelRenote: "চ্যানেলে রিনোট" +inChannelQuote: "চ্যানেলে উদ্ধৃতি" pinnedNote: "পিন করা নোট" pinned: "পিন করা" you: "আপনি" @@ -108,6 +121,10 @@ sensitive: "সংবেদনশীল বিষয়বস্তু" add: "যুক্ত করুন" reaction: "প্রতিক্রিয়া" reactions: "প্রতিক্রিয়া" +emojiPicker: "ইমোজি পিকার" +pinnedEmojisForReactionSettingDescription: "রিঅ্যাকশন দেয়ার সময় আপনি ইমোজিটিকে পিন করা এবং প্রদর্শিত হওয়ার জন্য সেট করতে পারেন।" +pinnedEmojisSettingDescription: "ইমোজি ইনপুট দেয়ার সময় আপনি ইমোজিটিকে পিন করা এবং প্রদর্শিত হওয়ার জন্য সেট করতে পারেন।" +emojiPickerDisplay: "পিকার ডিসপ্লে" reactionSettingDescription2: "পুনরায় সাজাতে টেনে আনুন, মুছতে ক্লিক করুন, যোগ করতে + টিপুন।" rememberNoteVisibility: "নোটের দৃশ্যমান্যতার সেটিংস মনে রাখুন" attachCancel: "অ্যাটাচমেন্ট সরান " @@ -1034,6 +1051,7 @@ _2fa: step3: "অ্যাপে প্রদর্শিত টোকেনটি লিখুন এবং আপনার কাজ শেষ।" step4: "আপনাকে এখন থেকে লগ ইন করার সময়, এইভাবে টোকেন লিখতে হবে।" securityKeyInfo: "আপনি একটি হার্ডওয়্যার সিকিউরিটি কী ব্যবহার করে লগ ইন করতে পারেন যা FIDO2 বা ডিভাইসের ফিঙ্গারপ্রিন্ট সেন্সর বা পিন সমর্থন করে৷" + renewTOTPCancel: "না, ধন্যবাদ" _permissions: "read:account": "অ্যাকাউন্টের তথ্য দেখুন" "write:account": "অ্যাকাউন্টের তথ্য সম্পাদন করুন" diff --git a/locales/id-ID.yml b/locales/id-ID.yml index dc5600151a..156af44d89 100644 --- a/locales/id-ID.yml +++ b/locales/id-ID.yml @@ -121,6 +121,10 @@ sensitive: "Konten sensitif" add: "Tambahkan" reaction: "Reaksi" reactions: "Reaksi" +emojiPicker: "Emoji Picker" +pinnedEmojisForReactionSettingDescription: "Atur sematan emoji pada reaksi" +pinnedEmojisSettingDescription: "Atur sematan emoji pada masukan emoji" +emojiPickerDisplay: "Tampilan Emoji Picker" reactionSettingDescription2: "Geser untuk memindah urutan emoji, klik untuk menghapus, tekan \"+\" untuk menambahkan" rememberNoteVisibility: "Ingat pengaturan visibilitas catatan" attachCancel: "Hapus lampiran" @@ -641,6 +645,7 @@ smtpSecure: "Gunakan SSL/TLS implisit untuk koneksi SMTP" smtpSecureInfo: "Matikan ini ketika menggunakan STARTTLS" testEmail: "Tes pengiriman surel" wordMute: "Bisukan kata" +hardWordMute: "Pembisuan kata keras" regexpError: "Kesalahan ekspresi reguler" regexpErrorDescription: "Galat terjadi pada baris {line} ekspresi reguler dari {tab} kata yang dibisukan:" instanceMute: "Bisukan instansi" @@ -1154,6 +1159,7 @@ tosAndPrivacyPolicy: "Syarat dan Ketentuan serta Kebijakan Privasi" avatarDecorations: "Dekorasi avatar" attach: "Lampirkan" detach: "Hapus" +detachAll: "Lepas Semua" angle: "Sudut" flip: "Balik" showAvatarDecorations: "Tampilkan dekorasi avatar" @@ -1168,6 +1174,7 @@ doReaction: "Tambahkan reaksi" code: "Kode" reloadRequiredToApplySettings: "Muat ulang diperlukan untuk menerapkan pengaturan." remainingN: "Sisa : {n}" +decorate: "Dekor" _announcement: forExistingUsers: "Hanya pengguna yang telah ada" forExistingUsersDescription: "Pengumuman ini akan dimunculkan ke pengguna yang sudah ada dari titik waktu publikasi jika dinyalakan. Apabila dimatikan, mereka yang baru mendaftar setelah publikasi ini akan juga melihatnya." @@ -1215,6 +1222,7 @@ _initialTutorial: followers: "Perlihatkan ke pengikut saja. Hanya pengikut yang dapat melihat postinganmu dan tidak dapat direnote oleh siapapun." direct: "Hanya perlihatkan ke pengguna spesifik dan penerima akan diberi tahu. Dapat juga digunakan sebagai alternatif dari pesan langsung." _cw: + title: "Peringatan Konten (CW)" _exampleNote: cw: "Peringatan: Bikin Lapar!" note: "Baru aja makan donat berlapis coklat 🍩😋" diff --git a/locales/ko-GS.yml b/locales/ko-GS.yml index 37bdf1e577..566667ba79 100644 --- a/locales/ko-GS.yml +++ b/locales/ko-GS.yml @@ -260,6 +260,7 @@ removed: "뭉캣십니다" removeAreYouSure: "‘{x}’(얼)럴 뭉캡니꺼?" deleteAreYouSure: "‘{x}’(얼)럴 뭉캡니꺼?" resetAreYouSure: "아시로 데돌립니꺼?" +areYouSure: "갠찮십니꺼?" saved: "저장햇십니다" messaging: "대화" upload: "올리기" @@ -458,6 +459,7 @@ noMessagesYet: "아직 대화가 없십니다" newMessageExists: "새 메시지가 있십니다" onlyOneFileCanBeAttached: "메시지엔 파일 하나까제밖에 몬 넣십니다" invitations: "초대하기" +invitationCode: "초대장" checking: "학인하고 잇십니다" passwordMatched: "맞십니다" passwordNotMatched: "안 맞십니다" @@ -564,6 +566,11 @@ removeAllFollowing: "팔로잉 말캉 무루기" removeAllFollowingDescription: "{host} 서버랑 걸어놓은 모든 팔로잉을 무룹니다. 고 서버가 아예 없어지삐맀든가, 그런 경우에 하이소." userSuspended: "요 게정은... 얼어 있십니다." userSilenced: "요 게정은... 수ᇚ혀 있십니다." +relays: "릴레이" +addRelay: "릴레이 옇기" +addedRelays: "옇은 릴레이" +enableInfiniteScroll: "알아서 더 보기" +author: "맨던 사람" manage: "간리" emailServer: "전자우펜 서버" email: "전자우펜" @@ -572,6 +579,8 @@ smtpHost: "호스트 이럼" smtpPort: "포트" smtpUser: "사용자 이럼" smtpPass: "비밀번호" +display: "보기" +create: "맨걸기" abuseReports: "신고하기" reportAbuse: "신고하기" reportAbuseRenote: "리노트 신고하기" @@ -583,6 +592,7 @@ forwardReport: "웬겍 서버에 신고 보내기" random: "무작이" system: "시스템" clip: "클립 맨걸기" +createNew: "새로 맨걸기" notesCount: "노트 수" renotesCount: "리노트한 수" renotedCount: "리노트덴 수" @@ -608,6 +618,7 @@ tools: "도구" like: "좋네예!" unlike: "좋네예 무루기" numberOfLikes: "좋네예 수" +show: "보기" roles: "옉할" role: "옉할" noRole: "옉할이 없십니다" @@ -637,6 +648,8 @@ _gallery: _email: _follow: title: "새 팔로워가 잇십니다" +_serverDisconnectedBehavior: + reload: "알아서 새로곤침" _channel: removeBanner: "배너 뭉캐기" _theme: diff --git a/locales/ko-KR.yml b/locales/ko-KR.yml index 63d0812e93..4a13012eed 100644 --- a/locales/ko-KR.yml +++ b/locales/ko-KR.yml @@ -425,9 +425,9 @@ setupOf2fa: "2단계 인증 설정" totp: "인증 앱" totpDescription: "인증 앱을 사용하여 일회성 비밀번호 입력" moderator: "모더레이터" -moderation: "모더레이션" -moderationNote: "모더레이션 노트" -addModerationNote: "모더레이션 노트 추가하기" +moderation: "조정" +moderationNote: "조정 기록" +addModerationNote: "조정 기록 추가하기" moderationLogs: "모더레이션 로그" nUsersMentioned: "{n}명이 언급함" securityKeyAndPasskey: "보안 키 또는 패스 키" @@ -513,7 +513,7 @@ dayOverDayChanges: "어제보다" appearance: "모양" clientSettings: "클라이언트 설정" accountSettings: "계정 설정" -promotion: "프로모션" +promotion: "홍보" promote: "프로모션하기" numberOfDays: "며칠동안" hideThisNote: "이 노트를 숨기기" @@ -863,8 +863,8 @@ devMode: "개발자 모드" keepCw: "CW 유지하기" pubSub: "Pub/Sub 계정" lastCommunication: "마지막 통신" -resolved: "해결됨" -unresolved: "해결되지 않음" +resolved: "처리함" +unresolved: "처리되지 않음" breakFollow: "팔로워 해제" breakFollowConfirm: "팔로우를 해제하시겠습니까?" itsOn: "켜져 있습니다" @@ -1181,6 +1181,8 @@ remainingN: "나머지: {n}" overwriteContentConfirm: "현재 내용을 덮어쓰기 합니다. 계속 진행하시겠습니까?" seasonalScreenEffect: "계절에 따른 효과 보이기" decorate: "장식하기" +addMfmFunction: "장식 추가하기" +enableQuickAddMfmFunction: "상급자용 MFM 선택기 표시하기" _announcement: forExistingUsers: "기존 유저에게만 알림" forExistingUsersDescription: "활성화하면 이 공지사항을 게시한 시점에서 이미 가입한 유저에게만 표시합니다. 비활성화하면 게시 후에 가입한 유저에게도 표시합니다." @@ -1557,7 +1559,7 @@ _role: name: "역할 이름" description: "역할 설명" permission: "역할 권한" - descriptionOfPermission: "모더레이터는 기본적인 중재와 관련된 작업을 수행할 수 있습니다.\n관리자는 서버의 모든 설정을 변경할 수 있습니다." + descriptionOfPermission: "조정자는 기본적인 조정 작업을 진행할 수 있습니다.\n관리자는 서버의 모든 설정을 변경할 수 있습니다." assignTarget: "할당 대상" descriptionOfAssignTarget: "수동을 선택하면 누가 이 역할에 포함되는지를 수동으로 관리할 수 있습니다.\n조건부를 선택하면 조건을 설정해 일치하는 사용자를 자동으로 포함되게 할 수 있습니다." manual: "수동" @@ -1628,7 +1630,7 @@ _role: or: "다음을 하나라도 만족" not: "다음을 만족하지 않음" _sensitiveMediaDetection: - description: "기계학습을 통해 자동으로 민감한 미디어를 탐지하여, 모더레이션에 참고할 수 있도록 합니다. 서버의 부하를 약간 증가시킵니다." + description: "기계 학습으로 민감한 미디어를 알아서 찾아내어 조정에 참고하도록 합니다. 서버가 부하를 다소 받습니다." sensitivity: "탐지 민감도" sensitivityDescription: "민감도가 낮을수록 안전한 미디어가 잘못 탐지될 확률이 줄어들며, 높을수록 민감한 미디어가 탐지되지 않을 확률이 줄어듭니다." setSensitiveFlagAutomatically: "자동으로 NSFW로 설정하기" @@ -1933,6 +1935,55 @@ _permissions: "write:flash": "Play를 조작합니다" "read:flash-likes": "Play의 좋아요를 봅니다" "write:flash-likes": "Play의 좋아요를 조작합니다" + "read:admin:abuse-user-reports": "사용자 신고 보기" + "write:admin:delete-account": "사용자 계정 삭제하기" + "write:admin:delete-all-files-of-a-user": "모든 사용자 파일 삭제하기" + "read:admin:index-stats": "데이터베이스 색인 정보 보기" + "read:admin:table-stats": "데이터베이스 테이블 정보 보기" + "read:admin:user-ips": "사용자 IP 주소 보기" + "read:admin:meta": "인스턴스 메타데이터 보기" + "write:admin:reset-password": "사용자 비밀번호 재설정하기" + "write:admin:resolve-abuse-user-report": "사용자 신고 처리하기" + "write:admin:send-email": "이메일 보내기" + "read:admin:server-info": "서버 정보 보기" + "read:admin:show-moderation-log": "조정 기록 보기" + "read:admin:show-user": "사용자 개인정보 보기" + "read:admin:show-users": "사용자 개인정보 보기" + "write:admin:suspend-user": "사용자 정지하기" + "write:admin:unset-user-avatar": "사용자 아바타 삭제하기" + "write:admin:unset-user-banner": "사용자 배너 삭제하기" + "write:admin:unsuspend-user": "사용자 정지 해제하기" + "write:admin:meta": "인스턴스 메타데이터 수정하기" + "write:admin:user-note": "조정 기록 수정하기" + "write:admin:roles": "역할 수정하기" + "read:admin:roles": "역할 보기" + "write:admin:relays": "릴레이 수정하기" + "read:admin:relays": "릴레이 보기" + "write:admin:invite-codes": "초대 코드 수정하기" + "read:admin:invite-codes": "초대 코드 보기" + "write:admin:announcements": "공지사항 수정하기" + "read:admin:announcements": "공지사항 보기" + "write:admin:avatar-decorations": "아바타 꾸미기 수정하기" + "read:admin:avatar-decorations": "아바타 꾸미기 보기" + "write:admin:federation": "연합 정보 수정하기" + "write:admin:account": "사용자 계정 수정하기" + "read:admin:account": "사용자 정보 보기" + "write:admin:emoji": "이모지 수정하기" + "read:admin:emoji": "이모지 보기" + "write:admin:queue": "작업 대기열 수정하기" + "read:admin:queue": "작업 대기열 정보 보기" + "write:admin:promo": "홍보 기록 수정하기" + "write:admin:drive": "사용자 드라이브 수정하기" + "read:admin:drive": "사용자 드라이브 정보 보기" + "read:admin:stream": "관리자용 Websocket API 사용하기" + "write:admin:ad": "광고 수정하기" + "read:admin:ad": "광고 보기" + "write:invite-codes": "초대 코드 만들기" + "read:invite-codes": "초대 코드 불러오기" + "write:clip-favorite": "클립의 좋아요 수정하기" + "read:clip-favorite": "클립의 좋아요 보기" + "read:federation": "연합 정보 불러오기" + "write:report-abuse": "위반 내용 신고하기" _auth: shareAccessTitle: "어플리케이션의 접근 허가" shareAccess: "\"{name}\" 이 계정에 접근하는 것을 허용하시겠습니까?" @@ -2267,21 +2318,21 @@ _moderationLogTypes: updateCustomEmoji: "커스텀 이모지 수정" deleteCustomEmoji: "커스텀 이모지 삭제" updateServerSettings: "서버 설정 갱신" - updateUserNote: "모더레이션 노트 갱신" + updateUserNote: "조정 기록 갱신" deleteDriveFile: "파일 삭제" deleteNote: "노트 삭제" - createGlobalAnnouncement: "전역 공지사항 생성" - createUserAnnouncement: "유저 공지사항 생성" - updateGlobalAnnouncement: "전역 공지사항 수정" - updateUserAnnouncement: "유저 공지사항 수정" - deleteGlobalAnnouncement: "전역 공지사항 삭제" - deleteUserAnnouncement: "유저 공지사항 삭제" + createGlobalAnnouncement: "모든 공지사항 만들기" + createUserAnnouncement: "사용자 공지사항 만들기" + updateGlobalAnnouncement: "모든 공지사항 수정" + updateUserAnnouncement: "사용자 공지사항 수정" + deleteGlobalAnnouncement: "모든 공지사항 삭제" + deleteUserAnnouncement: "사용자 공지사항 삭제" resetPassword: "비밀번호 재설정" suspendRemoteInstance: "리모트 서버를 정지" unsuspendRemoteInstance: "리모트 서버의 정지를 해제" markSensitiveDriveFile: "파일에 열람주의를 설정" unmarkSensitiveDriveFile: "파일에 열람주의를 해제" - resolveAbuseReport: "신고 해결" + resolveAbuseReport: "신고 처리" createInvitation: "초대 코드 생성" createAd: "광고 생성" deleteAd: "광고 삭제" diff --git a/locales/zh-TW.yml b/locales/zh-TW.yml index 782f871b1e..36b6e77e9b 100644 --- a/locales/zh-TW.yml +++ b/locales/zh-TW.yml @@ -1181,6 +1181,8 @@ remainingN: "剩餘:{n}" overwriteContentConfirm: "確定要覆蓋目前的內容嗎?" seasonalScreenEffect: "隨季節變換畫面的呈現" decorate: "設置頭像裝飾" +addMfmFunction: "插入MFM功能語法" +enableQuickAddMfmFunction: "顯示高級MFM選擇器" _announcement: forExistingUsers: "僅限既有的使用者" forExistingUsersDescription: "啟用代表僅向現存使用者顯示;停用代表張貼後註冊的新使用者也會看到。" diff --git a/package.json b/package.json index f245d62bcb..49de5a5efd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "misskey", - "version": "2023.12.1", + "version": "2023.12.2", "codename": "nasubi", "repository": { "type": "git", @@ -18,7 +18,7 @@ "build-assets": "node ./scripts/build-assets.mjs", "build": "pnpm build-pre && pnpm -r build && pnpm build-assets", "build-storybook": "pnpm --filter frontend build-storybook", - "build-misskey-js-with-types": "pnpm --filter backend build && pnpm --filter backend generate-api-json && ncp packages/backend/built/api.json packages/misskey-js/generator/api.json && pnpm --filter misskey-js update-autogen-code && pnpm --filter misskey-js build", + "build-misskey-js-with-types": "pnpm --filter backend build && pnpm --filter backend generate-api-json && ncp packages/backend/built/api.json packages/misskey-js/generator/api.json && pnpm --filter misskey-js update-autogen-code && pnpm --filter misskey-js build && pnpm --filter misskey-js api", "start": "pnpm check:connect && cd packages/backend && node ./built/boot/entry.js", "start:test": "cd packages/backend && cross-env NODE_ENV=test node ./built/boot/entry.js", "init": "pnpm migrate", diff --git a/packages/backend/migration/1703658526000-supportTrueMailApi.js b/packages/backend/migration/1703658526000-supportTrueMailApi.js new file mode 100644 index 0000000000..0054d54122 --- /dev/null +++ b/packages/backend/migration/1703658526000-supportTrueMailApi.js @@ -0,0 +1,20 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class SupportTrueMailApi1703658526000 { + name = 'SupportTrueMailApi1703658526000' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ADD "truemailInstance" character varying(1024)`); + await queryRunner.query(`ALTER TABLE "meta" ADD "truemailAuthKey" character varying(1024)`); + await queryRunner.query(`ALTER TABLE "meta" ADD "enableTruemailApi" boolean NOT NULL DEFAULT false`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "enableTruemailApi"`); + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "truemailInstance"`); + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "truemailAuthKey"`); + } +} diff --git a/packages/backend/package.json b/packages/backend/package.json index 4d1e9936aa..7b9654c207 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -74,6 +74,8 @@ "@fastify/multipart": "8.0.0", "@fastify/static": "6.12.0", "@fastify/view": "8.2.0", + "@misskey-dev/sharp-read-bmp": "^1.1.1", + "@misskey-dev/summaly": "^5.0.3", "@nestjs/common": "10.2.10", "@nestjs/core": "10.2.10", "@nestjs/testing": "10.2.10", @@ -157,11 +159,9 @@ "sanitize-html": "2.11.0", "secure-json-parse": "2.7.0", "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.20", "tinycolor2": "1.6.0", "tmp": "0.2.1", @@ -177,6 +177,7 @@ }, "devDependencies": { "@jest/globals": "29.7.0", + "@misskey-dev/eslint-plugin": "^1.0.0", "@simplewebauthn/typescript-types": "8.3.4", "@swc/jest": "0.2.29", "@types/accepts": "1.3.7", diff --git a/packages/backend/src/core/DriveService.ts b/packages/backend/src/core/DriveService.ts index 484f4fc52e..04f0e38e6f 100644 --- a/packages/backend/src/core/DriveService.ts +++ b/packages/backend/src/core/DriveService.ts @@ -7,7 +7,7 @@ import { randomUUID } from 'node:crypto'; import * as fs from 'node:fs'; import { Inject, Injectable } from '@nestjs/common'; import sharp from 'sharp'; -import { sharpBmp } from 'sharp-read-bmp'; +import { sharpBmp } from '@misskey-dev/sharp-read-bmp'; import { IsNull } from 'typeorm'; import { DeleteObjectCommandInput, PutObjectCommandInput, NoSuchKey } from '@aws-sdk/client-s3'; import { DI } from '@/di-symbols.js'; diff --git a/packages/backend/src/core/EmailService.ts b/packages/backend/src/core/EmailService.ts index 7fc7800783..7e812b4df2 100644 --- a/packages/backend/src/core/EmailService.ts +++ b/packages/backend/src/core/EmailService.ts @@ -156,7 +156,7 @@ export class EmailService { @bindThis public async validateEmailForAccount(emailAddress: string): Promise<{ available: boolean; - reason: null | 'used' | 'format' | 'disposable' | 'mx' | 'smtp' | 'banned'; + reason: null | 'used' | 'format' | 'disposable' | 'mx' | 'smtp' | 'banned' | 'network' | 'blacklist'; }> { const meta = await this.metaService.fetch(); @@ -173,6 +173,8 @@ export class EmailService { if (meta.enableActiveEmailValidation) { if (meta.enableVerifymailApi && meta.verifymailAuthKey != null) { validated = await this.verifyMail(emailAddress, meta.verifymailAuthKey); + } else if (meta.enableTruemailApi && meta.truemailInstance && meta.truemailAuthKey != null) { + validated = await this.trueMail(meta.truemailInstance, emailAddress, meta.truemailAuthKey); } else { validated = await validateEmail({ email: emailAddress, @@ -201,6 +203,8 @@ export class EmailService { validated.reason === 'disposable' ? 'disposable' : validated.reason === 'mx' ? 'mx' : validated.reason === 'smtp' ? 'smtp' : + validated.reason === 'network' ? 'network' : + validated.reason === 'blacklist' ? 'blacklist' : null, }; } @@ -265,4 +269,67 @@ export class EmailService { reason: null, }; } + + private async trueMail(truemailInstance: string, emailAddress: string, truemailAuthKey: string): Promise<{ + valid: boolean; + reason: 'used' | 'format' | 'blacklist' | 'mx' | 'smtp' | 'network' | T | null; + }> { + const endpoint = truemailInstance + '?email=' + emailAddress; + try { + const res = await this.httpRequestService.send(endpoint, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Accept: 'application/json', + Authorization: truemailAuthKey + }, + }); + + const json = (await res.json()) as { + email: string; + success: boolean; + errors?: { + list_match?: string; + regex?: string; + mx?: string; + smtp?: string; + } | null; + }; + + if (json.email === undefined || (json.email !== undefined && json.errors?.regex)) { + return { + valid: false, + reason: 'format', + }; + } + if (json.errors?.smtp) { + return { + valid: false, + reason: 'smtp', + }; + } + if (json.errors?.mx) { + return { + valid: false, + reason: 'mx', + }; + } + if (!json.success) { + return { + valid: false, + reason: json.errors?.list_match as T || 'blacklist', + }; + } + + return { + valid: true, + reason: null, + }; + } catch (error) { + return { + valid: false, + reason: 'network', + }; + } + } } diff --git a/packages/backend/src/logger.ts b/packages/backend/src/logger.ts index 5c10559ec6..0a19036c97 100644 --- a/packages/backend/src/logger.ts +++ b/packages/backend/src/logger.ts @@ -71,8 +71,11 @@ export default class Logger { let log = `${l} ${worker}\t[${contexts.join(' ')}]\t${m}`; if (envOption.withLogTime) log = chalk.gray(time) + ' ' + log; - console.log(important ? chalk.bold(log) : log); - if (level === 'error' && data) console.log(data); + const args: unknown[] = [important ? chalk.bold(log) : log]; + if (data != null) { + args.push(data); + } + console.log(...args); } @bindThis diff --git a/packages/backend/src/models/Meta.ts b/packages/backend/src/models/Meta.ts index 818557dab3..9909e8932a 100644 --- a/packages/backend/src/models/Meta.ts +++ b/packages/backend/src/models/Meta.ts @@ -457,6 +457,23 @@ export class MiMeta { }) public verifymailAuthKey: string | null; + @Column('boolean', { + default: false, + }) + public enableTruemailApi: boolean; + + @Column('varchar', { + length: 1024, + nullable: true, + }) + public truemailInstance: string | null; + + @Column('varchar', { + length: 1024, + nullable: true, + }) + public truemailAuthKey: string | null; + @Column('boolean', { default: true, }) diff --git a/packages/backend/src/server/FileServerService.ts b/packages/backend/src/server/FileServerService.ts index 0c7fc8cefe..f59996ce17 100644 --- a/packages/backend/src/server/FileServerService.ts +++ b/packages/backend/src/server/FileServerService.ts @@ -9,7 +9,7 @@ import { dirname } from 'node:path'; import { Inject, Injectable } from '@nestjs/common'; import rename from 'rename'; import sharp from 'sharp'; -import { sharpBmp } from 'sharp-read-bmp'; +import { sharpBmp } from '@misskey-dev/sharp-read-bmp'; import type { Config } from '@/config.js'; import type { MiDriveFile, DriveFilesRepository } from '@/models/_.js'; import { DI } from '@/di-symbols.js'; diff --git a/packages/backend/src/server/api/endpoints/admin/meta.ts b/packages/backend/src/server/api/endpoints/admin/meta.ts index 4ee549bf1f..b1e46c3404 100644 --- a/packages/backend/src/server/api/endpoints/admin/meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/meta.ts @@ -284,6 +284,18 @@ export const meta = { type: 'string', optional: false, nullable: true, }, + enableTruemailApi: { + type: 'boolean', + optional: false, nullable: false, + }, + truemailInstance: { + type: 'string', + optional: false, nullable: true, + }, + truemailAuthKey: { + type: 'string', + optional: false, nullable: true, + }, enableChartsForRemoteUser: { type: 'boolean', optional: false, nullable: false, @@ -524,6 +536,9 @@ export default class extends Endpoint { // eslint- enableActiveEmailValidation: instance.enableActiveEmailValidation, enableVerifymailApi: instance.enableVerifymailApi, verifymailAuthKey: instance.verifymailAuthKey, + enableTruemailApi: instance.enableTruemailApi, + truemailInstance: instance.truemailInstance, + truemailAuthKey: instance.truemailAuthKey, enableChartsForRemoteUser: instance.enableChartsForRemoteUser, enableChartsForFederatedInstances: instance.enableChartsForFederatedInstances, enableServerMachineStats: instance.enableServerMachineStats, diff --git a/packages/backend/src/server/api/endpoints/admin/update-meta.ts b/packages/backend/src/server/api/endpoints/admin/update-meta.ts index dc0001a9d9..8a2dbc35db 100644 --- a/packages/backend/src/server/api/endpoints/admin/update-meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/update-meta.ts @@ -116,6 +116,9 @@ export const paramDef = { enableActiveEmailValidation: { type: 'boolean' }, enableVerifymailApi: { type: 'boolean' }, verifymailAuthKey: { type: 'string', nullable: true }, + enableTruemailApi: { type: 'boolean' }, + truemailInstance: { type: 'string', nullable: true }, + truemailAuthKey: { type: 'string', nullable: true }, enableChartsForRemoteUser: { type: 'boolean' }, enableChartsForFederatedInstances: { type: 'boolean' }, enableServerMachineStats: { type: 'boolean' }, @@ -474,6 +477,26 @@ export default class extends Endpoint { // eslint- set.verifymailAuthKey = ps.verifymailAuthKey; } } + + if (ps.enableTruemailApi !== undefined) { + set.enableTruemailApi = ps.enableTruemailApi; + } + + if (ps.truemailInstance !== undefined) { + if (ps.truemailInstance === '') { + set.truemailInstance = null; + } else { + set.truemailInstance = ps.truemailInstance; + } + } + + if (ps.truemailAuthKey !== undefined) { + if (ps.truemailAuthKey === '') { + set.truemailAuthKey = null; + } else { + set.truemailAuthKey = ps.truemailAuthKey; + } + } if (ps.enableChartsForRemoteUser !== undefined) { set.enableChartsForRemoteUser = ps.enableChartsForRemoteUser; diff --git a/packages/backend/src/server/web/UrlPreviewService.ts b/packages/backend/src/server/web/UrlPreviewService.ts index d590244e34..3fd88355dd 100644 --- a/packages/backend/src/server/web/UrlPreviewService.ts +++ b/packages/backend/src/server/web/UrlPreviewService.ts @@ -4,7 +4,7 @@ */ import { Inject, Injectable } from '@nestjs/common'; -import { summaly } from 'summaly'; +import { summaly } from '@misskey-dev/summaly'; import { DI } from '@/di-symbols.js'; import type { Config } from '@/config.js'; import { MetaService } from '@/core/MetaService.js'; diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 523fc281b3..864779fd9d 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -19,18 +19,18 @@ "dependencies": { "@discordapp/twemoji": "15.0.2", "@github/webauthn-json": "2.1.1", + "@misskey-dev/browser-image-resizer": "2.2.1-misskey.10", "@rollup/plugin-json": "6.1.0", "@rollup/plugin-replace": "5.0.5", "@rollup/pluginutils": "5.1.0", "@syuilo/aiscript": "0.16.0", "@tabler/icons-webfont": "2.44.0", "@twemoji/parser": "15.0.0", - "@vitejs/plugin-vue": "4.5.2", - "@vue/compiler-sfc": "3.3.12", + "@vitejs/plugin-vue": "5.0.2", + "@vue/compiler-sfc": "3.4.3", "aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.0.6", "astring": "1.8.6", "broadcast-channel": "7.0.0", - "browser-image-resizer": "github:misskey-dev/browser-image-resizer#v2.2.1-misskey.3", "buraha": "0.0.1", "canvas-confetti": "1.6.1", "chart.js": "4.4.1", @@ -45,7 +45,6 @@ "escape-regexp": "0.0.1", "estree-walker": "3.0.3", "eventemitter3": "5.0.1", - "gsap": "3.12.4", "idb-keyval": "6.2.1", "insert-text-at-cursor": "0.3.0", "is-file-animated": "1.0.2", @@ -70,10 +69,12 @@ "uuid": "9.0.1", "v-code-diff": "1.7.2", "vite": "5.0.10", - "vue": "3.3.12", + "vue": "3.4.3", "vuedraggable": "next" }, "devDependencies": { + "@misskey-dev/eslint-plugin": "^1.0.0", + "@misskey-dev/summaly": "^5.0.3", "@storybook/addon-actions": "7.6.5", "@storybook/addon-essentials": "7.6.5", "@storybook/addon-interactions": "7.6.5", @@ -107,7 +108,7 @@ "@typescript-eslint/eslint-plugin": "6.14.0", "@typescript-eslint/parser": "6.14.0", "@vitest/coverage-v8": "0.34.6", - "@vue/runtime-core": "3.3.12", + "@vue/runtime-core": "3.4.3", "acorn": "8.11.2", "cross-env": "7.0.3", "cypress": "13.6.1", @@ -127,11 +128,10 @@ "start-server-and-test": "2.0.3", "storybook": "7.6.5", "storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme", - "summaly": "github:misskey-dev/summaly", "vite-plugin-turbosnap": "1.0.3", "vitest": "0.34.6", "vitest-fetch-mock": "0.2.2", "vue-eslint-parser": "9.3.2", - "vue-tsc": "1.8.25" + "vue-tsc": "1.8.27" } } diff --git a/packages/frontend/src/components/MkButton.vue b/packages/frontend/src/components/MkButton.vue index 8b176eedaa..8d4631968d 100644 --- a/packages/frontend/src/components/MkButton.vue +++ b/packages/frontend/src/components/MkButton.vue @@ -131,6 +131,10 @@ function onMousedown(evt: MouseEvent): void { box-sizing: border-box; transition: background 0.1s ease; + &:hover { + text-decoration: none; + } + &:not(:disabled):hover { background: var(--buttonHoverBg); } diff --git a/packages/frontend/src/components/MkCodeEditor.vue b/packages/frontend/src/components/MkCodeEditor.vue index 6341c454ae..c8c3deb610 100644 --- a/packages/frontend/src/components/MkCodeEditor.vue +++ b/packages/frontend/src/components/MkCodeEditor.vue @@ -10,7 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-only