From ccba7fc9db6fe2878d8d87da850b4907f514a439 Mon Sep 17 00:00:00 2001 From: GeopJr Date: Sat, 11 Feb 2023 20:08:12 +0000 Subject: [PATCH 01/38] =?UTF-8?q?feat:=20=E2=9C=A8=20don't=20depend=20on?= =?UTF-8?q?=20an=20external=20service=20for=20urn:ietf:wg:oauth:2.0:oob=20?= =?UTF-8?q?(#9602)=20Co-authored-by:=20GeopJr=20=20Co-com?= =?UTF-8?q?mitted-by:=20GeopJr=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- locales/en-US.yml | 1 + .../src/server/api/mastodon/endpoints/auth.ts | 5 +---- packages/client/src/pages/auth.vue | 15 +++++++++++++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/locales/en-US.yml b/locales/en-US.yml index f43f01fb7..afcb0e24a 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -1294,6 +1294,7 @@ _auth: pleaseGoBack: "Please go back to the application" callback: "Returning to the application" denied: "Access denied" + copyAsk: "Please paste the following authorization code to the application" _antennaSources: all: "All posts" homeTimeline: "Posts from followed users" diff --git a/packages/backend/src/server/api/mastodon/endpoints/auth.ts b/packages/backend/src/server/api/mastodon/endpoints/auth.ts index 46b013f3f..6ada2e95a 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/auth.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/auth.ts @@ -58,10 +58,7 @@ export function apiAuthMastodon(router: Router): void { } const scopeArr = Array.from(pushScope); - let red = body.redirect_uris; - if (red === "urn:ietf:wg:oauth:2.0:oob") { - red = "https://thedesk.top/hello.html"; - } + const red = body.redirect_uris; const appData = await client.registerApp(body.client_name, { scopes: scopeArr, redirect_uris: red, diff --git a/packages/client/src/pages/auth.vue b/packages/client/src/pages/auth.vue index 9fc04d4f4..c3f580160 100644 --- a/packages/client/src/pages/auth.vue +++ b/packages/client/src/pages/auth.vue @@ -16,7 +16,11 @@

{{ session.app.isAuthorized ? i18n.t('already-authorized') : i18n.ts.allowed }}

-

{{ i18n.ts._auth.callback }}

+

{{ i18n.ts._auth.callback }}

+ + + +

{{ i18n.ts._auth.pleaseGoBack }}

@@ -32,6 +36,7 @@ import { defineComponent } from 'vue'; import XForm from './auth.form.vue'; import MkSignin from '@/components/MkSignin.vue'; +import MkKeyValue from '@/components/MkKeyValue.vue'; import * as os from '@/os'; import { login } from '@/account'; import { i18n } from '@/i18n'; @@ -40,6 +45,7 @@ export default defineComponent({ components: { XForm, MkSignin, + MkKeyValue }, props: ['token'], data() { @@ -48,6 +54,7 @@ export default defineComponent({ session: null, fetching: true, i18n, + auth_code: null }; }, mounted() { @@ -82,7 +89,11 @@ export default defineComponent({ if (this.session.app.callbackUrl) { const url = new URL(this.session.app.callbackUrl); if (['javascript:', 'file:', 'data:', 'mailto:', 'tel:'].includes(url.protocol)) throw new Error('invalid url'); - location.href = `${this.session.app.callbackUrl}?token=${this.session.token}&code=${this.session.token}&state=${getUrlParams().state || ''}`; + if (this.session.app.callbackUrl === "urn:ietf:wg:oauth:2.0:oob") { + this.auth_code = this.session.token; + } else { + location.href = `${this.session.app.callbackUrl}?token=${this.session.token}&code=${this.session.token}&state=${getUrlParams().state || ''}`; + } } }, onLogin(res) { login(res.i); From 1e7f8c3ab87a85f40c43eb2f9630767acddad749 Mon Sep 17 00:00:00 2001 From: ThatOneCalculator Date: Sat, 11 Feb 2023 13:04:22 -0800 Subject: [PATCH 02/38] chore: up calckey.js --- package.json | 2 +- packages/backend/package.json | 2 +- packages/client/package.json | 2 +- packages/sw/package.json | 2 +- pnpm-lock.yaml | 32 +++++++++++++++----------------- 5 files changed, 19 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index 7cd7efc28..18df3e5b2 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "@bull-board/api": "^4.10.2", "@bull-board/ui": "^4.10.2", "@tensorflow/tfjs": "^3.21.0", - "calckey-js": "^0.0.20", + "calckey-js": "^0.0.22", "js-yaml": "4.1.0", "phosphor-icons": "^1.4.2", "seedrandom": "^3.0.5" diff --git a/packages/backend/package.json b/packages/backend/package.json index 80484f95c..c1af9b173 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -47,7 +47,7 @@ "blurhash": "1.1.5", "bull": "4.10.2", "cacheable-lookup": "7.0.0", - "calckey-js": "^0.0.20", + "calckey-js": "^0.0.22", "cbor": "8.1.0", "chalk": "5.2.0", "chalk-template": "0.4.0", diff --git a/packages/client/package.json b/packages/client/package.json index 5a184dbc0..fb63b52a6 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -33,7 +33,7 @@ "blurhash": "1.1.5", "broadcast-channel": "4.19.1", "browser-image-resizer": "https://github.com/misskey-dev/browser-image-resizer.git", - "calckey-js": "^0.0.20", + "calckey-js": "^0.0.22", "chart.js": "4.1.1", "chartjs-adapter-date-fns": "2.0.1", "chartjs-plugin-gradient": "0.5.1", diff --git a/packages/sw/package.json b/packages/sw/package.json index ae9d12f72..55a750eec 100644 --- a/packages/sw/package.json +++ b/packages/sw/package.json @@ -13,7 +13,7 @@ "@swc/cli": "^0.1.59", "@swc/core": "^1.3.26", "@swc/core-android-arm64": "1.3.11", - "calckey-js": "^0.0.20", + "calckey-js": "^0.0.22", "idb-keyval": "^6.2.0", "swc-loader": "^0.2.3", "webpack": "^5.75.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 54880d9c9..056b02cbf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,7 +12,7 @@ importers: '@tensorflow/tfjs': ^3.21.0 '@types/gulp': 4.0.10 '@types/gulp-rename': 2.0.1 - calckey-js: ^0.0.20 + calckey-js: ^0.0.22 cross-env: 7.0.3 cypress: 10.11.0 execa: 5.1.1 @@ -32,7 +32,7 @@ importers: '@bull-board/api': 4.10.2 '@bull-board/ui': 4.10.2 '@tensorflow/tfjs': 3.21.0_seedrandom@3.0.5 - calckey-js: 0.0.20 + calckey-js: 0.0.22 js-yaml: 4.1.0 phosphor-icons: 1.4.2 seedrandom: 3.0.5 @@ -126,7 +126,7 @@ importers: blurhash: 1.1.5 bull: 4.10.2 cacheable-lookup: 7.0.0 - calckey-js: ^0.0.20 + calckey-js: ^0.0.22 cbor: 8.1.0 chalk: 5.2.0 chalk-template: 0.4.0 @@ -245,7 +245,7 @@ importers: blurhash: 1.1.5 bull: 4.10.2 cacheable-lookup: 7.0.0 - calckey-js: 0.0.20 + calckey-js: 0.0.22 cbor: 8.1.0 chalk: 5.2.0 chalk-template: 0.4.0 @@ -414,7 +414,7 @@ importers: blurhash: 1.1.5 broadcast-channel: 4.19.1 browser-image-resizer: https://github.com/misskey-dev/browser-image-resizer.git - calckey-js: ^0.0.20 + calckey-js: ^0.0.22 chart.js: 4.1.1 chartjs-adapter-date-fns: 2.0.1 chartjs-plugin-gradient: 0.5.1 @@ -488,7 +488,7 @@ importers: blurhash: 1.1.5 broadcast-channel: 4.19.1 browser-image-resizer: github.com/misskey-dev/browser-image-resizer/0380d12c8e736788ea7f4e6e985175521ea7b23c - calckey-js: 0.0.20 + calckey-js: 0.0.22 chart.js: 4.1.1 chartjs-adapter-date-fns: 2.0.1_chart.js@4.1.1 chartjs-plugin-gradient: 0.5.1_chart.js@4.1.1 @@ -542,7 +542,7 @@ importers: '@swc/cli': ^0.1.59 '@swc/core': ^1.3.26 '@swc/core-android-arm64': 1.3.11 - calckey-js: ^0.0.20 + calckey-js: ^0.0.22 idb-keyval: ^6.2.0 swc-loader: ^0.2.3 webpack: ^5.75.0 @@ -550,7 +550,7 @@ importers: '@swc/cli': 0.1.59_@swc+core@1.3.26 '@swc/core': 1.3.26 '@swc/core-android-arm64': 1.3.11 - calckey-js: 0.0.20 + calckey-js: 0.0.22 idb-keyval: 6.2.0 swc-loader: 0.2.3_v4imsvpumnwpgduroyqmpcfjiy webpack: 5.75.0_@swc+core@1.3.26 @@ -3335,7 +3335,7 @@ packages: /axios/0.24.0: resolution: {integrity: sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==} dependencies: - follow-redirects: 1.15.2_debug@4.3.4 + follow-redirects: 1.15.2 transitivePeerDependencies: - debug dev: false @@ -3343,7 +3343,7 @@ packages: /axios/0.25.0_debug@4.3.4: resolution: {integrity: sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==} dependencies: - follow-redirects: 1.15.2_debug@4.3.4 + follow-redirects: 1.15.2 transitivePeerDependencies: - debug dev: true @@ -3351,7 +3351,7 @@ packages: /axios/1.2.2: resolution: {integrity: sha512-bz/J4gS2S3I7mpN/YZfGFTqhXTYzRho8Ay38w2otuuDR322KzFIWm/4W2K6gIwvWaws5n+mnb7D1lN9uD+QH6Q==} dependencies: - follow-redirects: 1.15.2_debug@4.3.4 + follow-redirects: 1.15.2 form-data: 4.0.0 proxy-from-env: 1.1.0 transitivePeerDependencies: @@ -3361,7 +3361,7 @@ packages: /axios/1.3.2: resolution: {integrity: sha512-1M3O703bYqYuPhbHeya5bnhpYVsDDRyQSabNja04mZtboLNSuZ4YrltestrLXfHgmzua4TpUqRiVKbiQuo2epw==} dependencies: - follow-redirects: 1.15.2_debug@4.3.4 + follow-redirects: 1.15.2 form-data: 4.0.0 proxy-from-env: 1.1.0 transitivePeerDependencies: @@ -3820,8 +3820,8 @@ packages: engines: {node: '>=6'} dev: true - /calckey-js/0.0.20: - resolution: {integrity: sha512-KqydxFuMKAEmi+NPOpNZfnq5Ik7w2eApY7hc2MxrqIkcuy/lgUv8io4rnNx512fHppEHtV7AVxovU2//buvgZA==} + /calckey-js/0.0.22: + resolution: {integrity: sha512-So4Jc3w5QiwNO+8yLomjgNvHR9luKZ5bGLqjIEzAMsD/bIvUqWvriQAyWHN4EweyQUJ8UZCXBG9iyVX8VjtiXw==} dependencies: autobind-decorator: 2.4.0 eventemitter3: 4.0.7 @@ -6301,7 +6301,7 @@ packages: readable-stream: 2.3.7 dev: true - /follow-redirects/1.15.2_debug@4.3.4: + /follow-redirects/1.15.2: resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} engines: {node: '>=4.0'} peerDependencies: @@ -6309,8 +6309,6 @@ packages: peerDependenciesMeta: debug: optional: true - dependencies: - debug: 4.3.4 /for-each/0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} From 13af80454322a07af6929abae30b6eef8e584505 Mon Sep 17 00:00:00 2001 From: daikei Date: Sat, 11 Feb 2023 21:05:31 +0000 Subject: [PATCH 03/38] Discard notes made before Fedi's existence, or after today (#9605) This PR should kill #9531 - Safeguarding against posts that are made before 2007 (Identica being made in 2008, the 'first ever activitypub software' according to wikipedia.) Personally, if gone unnoticed, I believe that notes from the past can be used as an attack vector to silently flood a database. Co-authored-by: Kio-td Reviewed-on: https://codeberg.org/calckey/calckey/pulls/9605 Co-authored-by: daikei Co-committed-by: daikei --- .../src/remote/activitypub/models/note.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/packages/backend/src/remote/activitypub/models/note.ts b/packages/backend/src/remote/activitypub/models/note.ts index 28ce46e30..e643e24c9 100644 --- a/packages/backend/src/remote/activitypub/models/note.ts +++ b/packages/backend/src/remote/activitypub/models/note.ts @@ -125,6 +125,23 @@ export async function createNote( logger.info(`Creating the Note: ${note.id}`); + // Skip if note is made before 2007 (1yr before Fedi was created) + // OR skip if note is made 3 days in advance + if (note.published) { + const DateChecker = new Date(note.published) + const FutureCheck = new Date() + FutureCheck.setDate(FutureCheck.getDate() + 3) // Allow some wiggle room for misconfigured hosts + if (DateChecker.getFullYear() < 2007) { + logger.warn('Note somehow made before Activitypub was created; discarding'); + return null; + } + if (DateChecker > FutureCheck) { + logger.warn('Note somehow made after today; discarding') + return null; + } + } + + // Fetch author const actor = (await resolvePerson( getOneApId(note.attributedTo), From 861fbcab41c44063de01ccfe41cf7a80acf702b6 Mon Sep 17 00:00:00 2001 From: daikei Date: Sat, 11 Feb 2023 21:09:43 +0000 Subject: [PATCH 04/38] Remove hardcoding of sounds (#9510) (#9607) Co-authored-by: Kio-td Reviewed-on: https://codeberg.org/calckey/calckey/pulls/9607 Co-authored-by: daikei Co-committed-by: daikei --- gulpfile.js | 3 +- .../assets/sounds/None.mp3 | 0 .../assets/sounds/aisha/1.mp3 | 0 .../assets/sounds/aisha/2.mp3 | 0 .../assets/sounds/aisha/3.mp3 | 0 .../assets/sounds/noizenecio/kick_gaba.mp3 | 0 .../assets/sounds/noizenecio/kick_gaba2.mp3 | 0 .../assets/sounds/syuilo/down.mp3 | 0 .../assets/sounds/syuilo/kick.mp3 | 0 .../sounds/syuilo/pirori-square-wet.mp3 | 0 .../assets/sounds/syuilo/pirori-wet.mp3 | 0 .../assets/sounds/syuilo/pirori.mp3 | 0 .../assets/sounds/syuilo/poi1.mp3 | 0 .../assets/sounds/syuilo/poi2.mp3 | 0 .../assets/sounds/syuilo/pope1.mp3 | 0 .../assets/sounds/syuilo/pope2.mp3 | 0 .../assets/sounds/syuilo/popo.mp3 | 0 .../assets/sounds/syuilo/queue-jammed.mp3 | 0 .../assets/sounds/syuilo/reverved.mp3 | 0 .../assets/sounds/syuilo/ryukyu.mp3 | 0 .../assets/sounds/syuilo/snare.mp3 | 0 .../assets/sounds/syuilo/square-pico.mp3 | 0 .../assets/sounds/syuilo/triple.mp3 | 0 .../assets/sounds/syuilo/up.mp3 | 0 .../assets/sounds/syuilo/waon.mp3 | 0 packages/backend/src/server/api/endpoints.ts | 2 ++ .../src/server/api/endpoints/get-sounds.ts | 28 +++++++++++++++++++ packages/client/src/pages/settings/sounds.vue | 28 ++----------------- packages/client/src/scripts/sound.ts | 2 +- 29 files changed, 35 insertions(+), 28 deletions(-) rename packages/{client => backend}/assets/sounds/None.mp3 (100%) rename packages/{client => backend}/assets/sounds/aisha/1.mp3 (100%) rename packages/{client => backend}/assets/sounds/aisha/2.mp3 (100%) rename packages/{client => backend}/assets/sounds/aisha/3.mp3 (100%) rename packages/{client => backend}/assets/sounds/noizenecio/kick_gaba.mp3 (100%) rename packages/{client => backend}/assets/sounds/noizenecio/kick_gaba2.mp3 (100%) rename packages/{client => backend}/assets/sounds/syuilo/down.mp3 (100%) rename packages/{client => backend}/assets/sounds/syuilo/kick.mp3 (100%) rename packages/{client => backend}/assets/sounds/syuilo/pirori-square-wet.mp3 (100%) rename packages/{client => backend}/assets/sounds/syuilo/pirori-wet.mp3 (100%) rename packages/{client => backend}/assets/sounds/syuilo/pirori.mp3 (100%) rename packages/{client => backend}/assets/sounds/syuilo/poi1.mp3 (100%) rename packages/{client => backend}/assets/sounds/syuilo/poi2.mp3 (100%) rename packages/{client => backend}/assets/sounds/syuilo/pope1.mp3 (100%) rename packages/{client => backend}/assets/sounds/syuilo/pope2.mp3 (100%) rename packages/{client => backend}/assets/sounds/syuilo/popo.mp3 (100%) rename packages/{client => backend}/assets/sounds/syuilo/queue-jammed.mp3 (100%) rename packages/{client => backend}/assets/sounds/syuilo/reverved.mp3 (100%) rename packages/{client => backend}/assets/sounds/syuilo/ryukyu.mp3 (100%) rename packages/{client => backend}/assets/sounds/syuilo/snare.mp3 (100%) rename packages/{client => backend}/assets/sounds/syuilo/square-pico.mp3 (100%) rename packages/{client => backend}/assets/sounds/syuilo/triple.mp3 (100%) rename packages/{client => backend}/assets/sounds/syuilo/up.mp3 (100%) rename packages/{client => backend}/assets/sounds/syuilo/waon.mp3 (100%) create mode 100644 packages/backend/src/server/api/endpoints/get-sounds.ts diff --git a/gulpfile.js b/gulpfile.js index 89a6acb83..87063c0bc 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -15,8 +15,9 @@ gulp.task('copy:backend:views', () => gulp.src('./packages/backend/src/server/web/views/**/*').pipe(gulp.dest('./packages/backend/built/server/web/views')) ); + gulp.task('copy:backend:custom', () => - gulp.src('./custom/assets/*').pipe(gulp.dest('./packages/backend/assets/')) + gulp.src('./custom/assets/**/*').pipe(gulp.dest('./packages/backend/assets/')) ); gulp.task('copy:client:fonts', () => diff --git a/packages/client/assets/sounds/None.mp3 b/packages/backend/assets/sounds/None.mp3 similarity index 100% rename from packages/client/assets/sounds/None.mp3 rename to packages/backend/assets/sounds/None.mp3 diff --git a/packages/client/assets/sounds/aisha/1.mp3 b/packages/backend/assets/sounds/aisha/1.mp3 similarity index 100% rename from packages/client/assets/sounds/aisha/1.mp3 rename to packages/backend/assets/sounds/aisha/1.mp3 diff --git a/packages/client/assets/sounds/aisha/2.mp3 b/packages/backend/assets/sounds/aisha/2.mp3 similarity index 100% rename from packages/client/assets/sounds/aisha/2.mp3 rename to packages/backend/assets/sounds/aisha/2.mp3 diff --git a/packages/client/assets/sounds/aisha/3.mp3 b/packages/backend/assets/sounds/aisha/3.mp3 similarity index 100% rename from packages/client/assets/sounds/aisha/3.mp3 rename to packages/backend/assets/sounds/aisha/3.mp3 diff --git a/packages/client/assets/sounds/noizenecio/kick_gaba.mp3 b/packages/backend/assets/sounds/noizenecio/kick_gaba.mp3 similarity index 100% rename from packages/client/assets/sounds/noizenecio/kick_gaba.mp3 rename to packages/backend/assets/sounds/noizenecio/kick_gaba.mp3 diff --git a/packages/client/assets/sounds/noizenecio/kick_gaba2.mp3 b/packages/backend/assets/sounds/noizenecio/kick_gaba2.mp3 similarity index 100% rename from packages/client/assets/sounds/noizenecio/kick_gaba2.mp3 rename to packages/backend/assets/sounds/noizenecio/kick_gaba2.mp3 diff --git a/packages/client/assets/sounds/syuilo/down.mp3 b/packages/backend/assets/sounds/syuilo/down.mp3 similarity index 100% rename from packages/client/assets/sounds/syuilo/down.mp3 rename to packages/backend/assets/sounds/syuilo/down.mp3 diff --git a/packages/client/assets/sounds/syuilo/kick.mp3 b/packages/backend/assets/sounds/syuilo/kick.mp3 similarity index 100% rename from packages/client/assets/sounds/syuilo/kick.mp3 rename to packages/backend/assets/sounds/syuilo/kick.mp3 diff --git a/packages/client/assets/sounds/syuilo/pirori-square-wet.mp3 b/packages/backend/assets/sounds/syuilo/pirori-square-wet.mp3 similarity index 100% rename from packages/client/assets/sounds/syuilo/pirori-square-wet.mp3 rename to packages/backend/assets/sounds/syuilo/pirori-square-wet.mp3 diff --git a/packages/client/assets/sounds/syuilo/pirori-wet.mp3 b/packages/backend/assets/sounds/syuilo/pirori-wet.mp3 similarity index 100% rename from packages/client/assets/sounds/syuilo/pirori-wet.mp3 rename to packages/backend/assets/sounds/syuilo/pirori-wet.mp3 diff --git a/packages/client/assets/sounds/syuilo/pirori.mp3 b/packages/backend/assets/sounds/syuilo/pirori.mp3 similarity index 100% rename from packages/client/assets/sounds/syuilo/pirori.mp3 rename to packages/backend/assets/sounds/syuilo/pirori.mp3 diff --git a/packages/client/assets/sounds/syuilo/poi1.mp3 b/packages/backend/assets/sounds/syuilo/poi1.mp3 similarity index 100% rename from packages/client/assets/sounds/syuilo/poi1.mp3 rename to packages/backend/assets/sounds/syuilo/poi1.mp3 diff --git a/packages/client/assets/sounds/syuilo/poi2.mp3 b/packages/backend/assets/sounds/syuilo/poi2.mp3 similarity index 100% rename from packages/client/assets/sounds/syuilo/poi2.mp3 rename to packages/backend/assets/sounds/syuilo/poi2.mp3 diff --git a/packages/client/assets/sounds/syuilo/pope1.mp3 b/packages/backend/assets/sounds/syuilo/pope1.mp3 similarity index 100% rename from packages/client/assets/sounds/syuilo/pope1.mp3 rename to packages/backend/assets/sounds/syuilo/pope1.mp3 diff --git a/packages/client/assets/sounds/syuilo/pope2.mp3 b/packages/backend/assets/sounds/syuilo/pope2.mp3 similarity index 100% rename from packages/client/assets/sounds/syuilo/pope2.mp3 rename to packages/backend/assets/sounds/syuilo/pope2.mp3 diff --git a/packages/client/assets/sounds/syuilo/popo.mp3 b/packages/backend/assets/sounds/syuilo/popo.mp3 similarity index 100% rename from packages/client/assets/sounds/syuilo/popo.mp3 rename to packages/backend/assets/sounds/syuilo/popo.mp3 diff --git a/packages/client/assets/sounds/syuilo/queue-jammed.mp3 b/packages/backend/assets/sounds/syuilo/queue-jammed.mp3 similarity index 100% rename from packages/client/assets/sounds/syuilo/queue-jammed.mp3 rename to packages/backend/assets/sounds/syuilo/queue-jammed.mp3 diff --git a/packages/client/assets/sounds/syuilo/reverved.mp3 b/packages/backend/assets/sounds/syuilo/reverved.mp3 similarity index 100% rename from packages/client/assets/sounds/syuilo/reverved.mp3 rename to packages/backend/assets/sounds/syuilo/reverved.mp3 diff --git a/packages/client/assets/sounds/syuilo/ryukyu.mp3 b/packages/backend/assets/sounds/syuilo/ryukyu.mp3 similarity index 100% rename from packages/client/assets/sounds/syuilo/ryukyu.mp3 rename to packages/backend/assets/sounds/syuilo/ryukyu.mp3 diff --git a/packages/client/assets/sounds/syuilo/snare.mp3 b/packages/backend/assets/sounds/syuilo/snare.mp3 similarity index 100% rename from packages/client/assets/sounds/syuilo/snare.mp3 rename to packages/backend/assets/sounds/syuilo/snare.mp3 diff --git a/packages/client/assets/sounds/syuilo/square-pico.mp3 b/packages/backend/assets/sounds/syuilo/square-pico.mp3 similarity index 100% rename from packages/client/assets/sounds/syuilo/square-pico.mp3 rename to packages/backend/assets/sounds/syuilo/square-pico.mp3 diff --git a/packages/client/assets/sounds/syuilo/triple.mp3 b/packages/backend/assets/sounds/syuilo/triple.mp3 similarity index 100% rename from packages/client/assets/sounds/syuilo/triple.mp3 rename to packages/backend/assets/sounds/syuilo/triple.mp3 diff --git a/packages/client/assets/sounds/syuilo/up.mp3 b/packages/backend/assets/sounds/syuilo/up.mp3 similarity index 100% rename from packages/client/assets/sounds/syuilo/up.mp3 rename to packages/backend/assets/sounds/syuilo/up.mp3 diff --git a/packages/client/assets/sounds/syuilo/waon.mp3 b/packages/backend/assets/sounds/syuilo/waon.mp3 similarity index 100% rename from packages/client/assets/sounds/syuilo/waon.mp3 rename to packages/backend/assets/sounds/syuilo/waon.mp3 diff --git a/packages/backend/src/server/api/endpoints.ts b/packages/backend/src/server/api/endpoints.ts index 6ee1a977e..35ab738a2 100644 --- a/packages/backend/src/server/api/endpoints.ts +++ b/packages/backend/src/server/api/endpoints.ts @@ -222,6 +222,7 @@ import * as ep___messaging_messages_create from "./endpoints/messaging/messages/ import * as ep___messaging_messages_delete from "./endpoints/messaging/messages/delete.js"; import * as ep___messaging_messages_read from "./endpoints/messaging/messages/read.js"; import * as ep___meta from "./endpoints/meta.js"; +import * as ep___sounds from "./endpoints/get-sounds.js"; import * as ep___miauth_genToken from "./endpoints/miauth/gen-token.js"; import * as ep___mute_create from "./endpoints/mute/create.js"; import * as ep___mute_delete from "./endpoints/mute/delete.js"; @@ -668,6 +669,7 @@ const eps = [ ["users/stats", ep___users_stats], ["admin/drive-capacity-override", ep___admin_driveCapOverride], ["fetch-rss", ep___fetchRss], + ["get-sounds", ep___sounds] ]; export interface IEndpointMeta { diff --git a/packages/backend/src/server/api/endpoints/get-sounds.ts b/packages/backend/src/server/api/endpoints/get-sounds.ts new file mode 100644 index 000000000..aa3ef24e7 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/get-sounds.ts @@ -0,0 +1,28 @@ +import { readdir } from "fs/promises"; +import define from "../define.js"; + +export const meta = { + tags: ["meta"], + requireCredential: false, + requireCredentialPrivateMode: false, +} as const; + +export const paramDef = { + type: "object", + properties: {}, + required: [], +} as const; + +export default define(meta, paramDef, async () => { + const music_files: (string|null)[] = [null, ]; + const directory = (await readdir('./assets/sounds', { withFileTypes: true })) + .filter(potentialFolder => potentialFolder.isDirectory()) + for await (const folder of directory) { + const files = (await readdir(`./assets/sounds/${folder.name}`)) + .filter(potentialSong => potentialSong.endsWith('.mp3')) + for await (const file of files) { + music_files.push(`${folder.name}/${file.replace('.mp3','')}`); + } + } + return music_files +}); diff --git a/packages/client/src/pages/settings/sounds.vue b/packages/client/src/pages/settings/sounds.vue index 970b75ca3..c2297e212 100644 --- a/packages/client/src/pages/settings/sounds.vue +++ b/packages/client/src/pages/settings/sounds.vue @@ -50,32 +50,8 @@ const sounds = ref({ channel: ColdDeviceStorage.get('sound_channel'), }); -const soundsTypes = [ - null, - 'syuilo/up', - 'syuilo/down', - 'syuilo/pope1', - 'syuilo/pope2', - 'syuilo/waon', - 'syuilo/popo', - 'syuilo/triple', - 'syuilo/poi1', - 'syuilo/poi2', - 'syuilo/pirori', - 'syuilo/pirori-wet', - 'syuilo/pirori-square-wet', - 'syuilo/square-pico', - 'syuilo/reverved', - 'syuilo/ryukyu', - 'syuilo/kick', - 'syuilo/snare', - 'syuilo/queue-jammed', - 'aisha/1', - 'aisha/2', - 'aisha/3', - 'noizenecio/kick_gaba', - 'noizenecio/kick_gaba2', -]; +const soundsTypes = await os.api('get-sounds') + async function edit(type) { const { canceled, result } = await os.form(i18n.t('_sfx.' + type), { diff --git a/packages/client/src/scripts/sound.ts b/packages/client/src/scripts/sound.ts index 82233dd6c..29dd181e9 100644 --- a/packages/client/src/scripts/sound.ts +++ b/packages/client/src/scripts/sound.ts @@ -7,7 +7,7 @@ export function getAudio(file: string, useCache = true): HTMLAudioElement { if (useCache && cache.has(file)) { audio = cache.get(file); } else { - audio = new Audio(`/client-assets/sounds/${file}.mp3`); + audio = new Audio(`/static-assets/sounds/${file}.mp3`); if (useCache) cache.set(file, audio); } return audio; From 1d89cc3e3d92f01be6fb84e89d97caa6b861c29f Mon Sep 17 00:00:00 2001 From: ThatOneCalculator Date: Sat, 11 Feb 2023 13:16:45 -0800 Subject: [PATCH 05/38] =?UTF-8?q?docs:=20=F0=9F=93=9D=20custom=20assets?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ custom/assets/badges/error.png | 3 +++ custom/assets/badges/info.png | 3 +++ custom/assets/badges/not-found.png | 3 +++ .../backend => custom}/assets/sounds/None.mp3 | 0 .../src/remote/activitypub/models/note.ts | 13 +++++++------ packages/backend/src/server/api/endpoints.ts | 2 +- .../src/server/api/endpoints/get-sounds.ts | 16 +++++++++------- packages/backend/src/server/api/index.ts | 10 ++++++---- packages/backend/src/server/index.ts | 14 ++++++++------ 10 files changed, 42 insertions(+), 24 deletions(-) create mode 100644 custom/assets/badges/error.png create mode 100644 custom/assets/badges/info.png create mode 100644 custom/assets/badges/not-found.png rename {packages/backend => custom}/assets/sounds/None.mp3 (100%) diff --git a/README.md b/README.md index 91a2c8809..55f599235 100644 --- a/README.md +++ b/README.md @@ -124,6 +124,8 @@ psql postgres -c "create database calckey with encoding = 'UTF8';" - To add custom CSS for all users, edit `./custom/assets/instance.css`. - To add static assets (such as images for the splash screen), place them in the `./custom/assets/` directory. They'll then be available on `https://yourinstance.tld/static-assets/filename.ext`. - To add custom locales, place them in the `./custom/locales/` directory. If you name your custom locale the same as an existing locale, it will overwrite it. If you give it a unique name, it will be added to the list. Also make sure that the first part of the filename matches the locale you're basing it on. (Example: `en-FOO.yml`) +- To add custom error images, place them in the `./custom/assets/badges` directory, replacing the files already there. +- To add custom sounds, place only mp3 files in the `./custom/assets/sounds` directory. - To update custom assets without rebuilding, just run `pnpm run gulp`. ## 🧑‍🔬 Configuring a new instance diff --git a/custom/assets/badges/error.png b/custom/assets/badges/error.png new file mode 100644 index 000000000..b2fd48b23 --- /dev/null +++ b/custom/assets/badges/error.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:227326c64cce0cd93b18b0065c97bc4887b1a895f377382a32c3058c5375abd0 +size 58350 diff --git a/custom/assets/badges/info.png b/custom/assets/badges/info.png new file mode 100644 index 000000000..10b1ef217 --- /dev/null +++ b/custom/assets/badges/info.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e7a4f2460b5ccbee9fab5bb93bc312125efd0eb1cd82cd56e5ecf0b4fc5d8ef7 +size 56191 diff --git a/custom/assets/badges/not-found.png b/custom/assets/badges/not-found.png new file mode 100644 index 000000000..eaf62f9e3 --- /dev/null +++ b/custom/assets/badges/not-found.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eb357df23841d87e0cda813bcaffe6152929c71703f8250206819fb0ed8ef1d8 +size 56874 diff --git a/packages/backend/assets/sounds/None.mp3 b/custom/assets/sounds/None.mp3 similarity index 100% rename from packages/backend/assets/sounds/None.mp3 rename to custom/assets/sounds/None.mp3 diff --git a/packages/backend/src/remote/activitypub/models/note.ts b/packages/backend/src/remote/activitypub/models/note.ts index e643e24c9..10ab5c66f 100644 --- a/packages/backend/src/remote/activitypub/models/note.ts +++ b/packages/backend/src/remote/activitypub/models/note.ts @@ -128,20 +128,21 @@ export async function createNote( // Skip if note is made before 2007 (1yr before Fedi was created) // OR skip if note is made 3 days in advance if (note.published) { - const DateChecker = new Date(note.published) - const FutureCheck = new Date() - FutureCheck.setDate(FutureCheck.getDate() + 3) // Allow some wiggle room for misconfigured hosts + const DateChecker = new Date(note.published); + const FutureCheck = new Date(); + FutureCheck.setDate(FutureCheck.getDate() + 3); // Allow some wiggle room for misconfigured hosts if (DateChecker.getFullYear() < 2007) { - logger.warn('Note somehow made before Activitypub was created; discarding'); + logger.warn( + "Note somehow made before Activitypub was created; discarding", + ); return null; } if (DateChecker > FutureCheck) { - logger.warn('Note somehow made after today; discarding') + logger.warn("Note somehow made after today; discarding"); return null; } } - // Fetch author const actor = (await resolvePerson( getOneApId(note.attributedTo), diff --git a/packages/backend/src/server/api/endpoints.ts b/packages/backend/src/server/api/endpoints.ts index 35ab738a2..7fb5fd320 100644 --- a/packages/backend/src/server/api/endpoints.ts +++ b/packages/backend/src/server/api/endpoints.ts @@ -669,7 +669,7 @@ const eps = [ ["users/stats", ep___users_stats], ["admin/drive-capacity-override", ep___admin_driveCapOverride], ["fetch-rss", ep___fetchRss], - ["get-sounds", ep___sounds] + ["get-sounds", ep___sounds], ]; export interface IEndpointMeta { diff --git a/packages/backend/src/server/api/endpoints/get-sounds.ts b/packages/backend/src/server/api/endpoints/get-sounds.ts index aa3ef24e7..f7edd3860 100644 --- a/packages/backend/src/server/api/endpoints/get-sounds.ts +++ b/packages/backend/src/server/api/endpoints/get-sounds.ts @@ -14,15 +14,17 @@ export const paramDef = { } as const; export default define(meta, paramDef, async () => { - const music_files: (string|null)[] = [null, ]; - const directory = (await readdir('./assets/sounds', { withFileTypes: true })) - .filter(potentialFolder => potentialFolder.isDirectory()) + const music_files: (string | null)[] = [null]; + const directory = ( + await readdir("./assets/sounds", { withFileTypes: true }) + ).filter((potentialFolder) => potentialFolder.isDirectory()); for await (const folder of directory) { - const files = (await readdir(`./assets/sounds/${folder.name}`)) - .filter(potentialSong => potentialSong.endsWith('.mp3')) + const files = (await readdir(`./assets/sounds/${folder.name}`)).filter( + (potentialSong) => potentialSong.endsWith(".mp3"), + ); for await (const file of files) { - music_files.push(`${folder.name}/${file.replace('.mp3','')}`); + music_files.push(`${folder.name}/${file.replace(".mp3", "")}`); } } - return music_files + return music_files; }); diff --git a/packages/backend/src/server/api/index.ts b/packages/backend/src/server/api/index.ts index 189705903..6d02ad0ab 100644 --- a/packages/backend/src/server/api/index.ts +++ b/packages/backend/src/server/api/index.ts @@ -61,10 +61,12 @@ router.use( }), ); -mastoRouter.use(koaBody({ - multipart: true, - urlencoded: true -})); +mastoRouter.use( + koaBody({ + multipart: true, + urlencoded: true, + }), +); apiMastodonCompatible(mastoRouter); diff --git a/packages/backend/src/server/index.ts b/packages/backend/src/server/index.ts index cd495971e..efdd746ee 100644 --- a/packages/backend/src/server/index.ts +++ b/packages/backend/src/server/index.ts @@ -72,9 +72,11 @@ app.use(mount("/proxy", proxyServer)); const router = new Router(); const mastoRouter = new Router(); -mastoRouter.use(koaBody({ - urlencoded: true -})); +mastoRouter.use( + koaBody({ + urlencoded: true, + }), +); // Routing router.use(activityPub.routes()); @@ -159,9 +161,9 @@ mastoRouter.post("/oauth/token", async (ctx) => { ctx.body = { error: "Invalid code" }; return; } - } + } if (client_id instanceof Array) { - client_id = client_id.toString();; + client_id = client_id.toString(); } else if (!client_id) { client_id = null; } @@ -169,7 +171,7 @@ mastoRouter.post("/oauth/token", async (ctx) => { const atData = await client.fetchAccessToken( client_id, body.client_secret, - m ? m[0] : '', + m ? m[0] : "", ); ctx.body = { access_token: atData.accessToken, From b2b619ffa718cfa247b6b354d803728d87781773 Mon Sep 17 00:00:00 2001 From: Evangelos Paterakis Date: Sat, 11 Feb 2023 23:28:46 +0200 Subject: [PATCH 06/38] =?UTF-8?q?fix:=20=F0=9F=90=9B=20100vh=20body=20back?= =?UTF-8?q?ground=20color?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/server/web/style.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/server/web/style.css b/packages/backend/src/server/web/style.css index 5072e0ad4..ee42b9deb 100644 --- a/packages/backend/src/server/web/style.css +++ b/packages/backend/src/server/web/style.css @@ -1,4 +1,4 @@ -html { +html, body { background-color: var(--bg); color: var(--fg); } From 9189ef29bab43af3f981b1497444477b36ef157f Mon Sep 17 00:00:00 2001 From: cutestnekoaqua Date: Sat, 11 Feb 2023 22:50:15 +0100 Subject: [PATCH 07/38] meow Co-authored-by: cutls --- packages/backend/package.json | 2 +- .../server/api/mastodon/endpoints/account.ts | 19 +++++++++++++++++++ pnpm-lock.yaml | 8 ++++---- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index c1af9b173..7a25ee76b 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -79,7 +79,7 @@ "koa-send": "5.0.1", "koa-slow": "2.1.0", "koa-views": "7.0.2", - "@cutls/megalodon": "5.1.15", + "@cutls/megalodon": "5.1.16", "mfm-js": "0.23.2", "mime-types": "2.1.35", "multer": "1.4.4-lts.1", diff --git a/packages/backend/src/server/api/mastodon/endpoints/account.ts b/packages/backend/src/server/api/mastodon/endpoints/account.ts index 0162951d6..2766dbdce 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/account.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/account.ts @@ -4,6 +4,23 @@ import { koaBody } from "koa-body"; import { getClient } from "../ApiMastodonCompatibleService.js"; import { toLimitToInt } from "./timeline.js"; +const relationshopModel = { + id: '', + following: false, + followed_by: false, + delivery_following: false, + blocking: false, + blocked_by: false, + muting: false, + muting_notifications: false, + requested: false, + domain_blocking: false, + showing_reblogs: false, + endorsed: false, + notifying: false, + note: '' +} + export function apiAccountMastodon(router: Router): void { router.get("/v1/accounts/verify_credentials", async (ctx, next) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; @@ -258,6 +275,8 @@ export function apiAccountMastodon(router: Router): void { try { const idsRaw = (ctx.query as any)["id[]"]; const ids = typeof idsRaw === "string" ? [idsRaw] : idsRaw; + relationshopModel.id = idsRaw || '1' + if (!idsRaw) return [relationshopModel] const data = (await client.getRelationships(ids)) as any; ctx.body = data.data; } catch (e: any) { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 056b02cbf..a4a61060c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -57,7 +57,7 @@ importers: '@bull-board/api': ^4.6.4 '@bull-board/koa': ^4.6.4 '@bull-board/ui': ^4.6.4 - '@cutls/megalodon': 5.1.15 + '@cutls/megalodon': 5.1.16 '@discordapp/twemoji': 14.0.2 '@elastic/elasticsearch': 7.17.0 '@koa/cors': 3.4.3 @@ -223,7 +223,7 @@ importers: '@bull-board/api': 4.10.2 '@bull-board/koa': 4.10.2_6tybghmia4wsnt33xeid7y4rby '@bull-board/ui': 4.10.2 - '@cutls/megalodon': 5.1.15 + '@cutls/megalodon': 5.1.16 '@discordapp/twemoji': 14.0.2 '@elastic/elasticsearch': 7.17.0 '@koa/cors': 3.4.3 @@ -847,8 +847,8 @@ packages: dependencies: '@jridgewell/trace-mapping': 0.3.9 - /@cutls/megalodon/5.1.15: - resolution: {integrity: sha512-4+mIKUYYr2CLY3idSxXk56WSTG9ww3opeenmsPRxftTwcjQTYxGntNkWmJWEbzeJ4rPslnvpwD7cFR62bPf41g==} + /@cutls/megalodon/5.1.16: + resolution: {integrity: sha512-s2U3qjcs86v0/p0EPwlQqSMh4UhAqTNxu8xUVsPvzrwXr5TrrJ5AVKunBm5582AEkx47nZkqm/98ZF2iHb0GtQ==} engines: {node: '>=15.0.0'} dependencies: '@types/oauth': 0.9.1 From 273ab9128415c8bbc2889370c5e62de4db824120 Mon Sep 17 00:00:00 2001 From: cutestnekoaqua Date: Sat, 11 Feb 2023 23:12:14 +0100 Subject: [PATCH 08/38] fix timelines --- packages/backend/src/server/api/mastodon/endpoints/timeline.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/backend/src/server/api/mastodon/endpoints/timeline.ts b/packages/backend/src/server/api/mastodon/endpoints/timeline.ts index 9caf43114..a2857e32c 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/timeline.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/timeline.ts @@ -6,8 +6,9 @@ import Autolinker from "autolinker"; import { ParsedUrlQuery } from "querystring"; export function toLimitToInt(q: ParsedUrlQuery) { + let object: any = q; if (q.limit) - if (typeof q.limit === "string") q.limit = parseInt(q.limit, 10).toString(); + if (typeof q.limit === "string") object.limit = parseInt(q.limit, 10); return q; } From 87c54e03d8ae47cb9695d3066753e222aa591f54 Mon Sep 17 00:00:00 2001 From: cutestnekoaqua Date: Sat, 11 Feb 2023 23:46:35 +0100 Subject: [PATCH 09/38] change name of Reactions bot --- packages/backend/src/server/api/mastodon/endpoints/status.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/server/api/mastodon/endpoints/status.ts b/packages/backend/src/server/api/mastodon/endpoints/status.ts index 3afd7e576..cce2e8e1d 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/status.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/status.ts @@ -435,7 +435,7 @@ export function statusModel( id: "9arzuvv0sw", username: "ReactionBot", acct: "ReactionBot", - display_name: "ReactionOfThisPost", + display_name: "ReactionsToThisPost", locked: false, created_at: now, followers_count: 0, From 0d836df218f45e21e94e04f5357f140910897b1e Mon Sep 17 00:00:00 2001 From: cutestnekoaqua Date: Sat, 11 Feb 2023 23:50:58 +0100 Subject: [PATCH 10/38] remove unneeded next middleware --- .../server/api/mastodon/endpoints/account.ts | 40 +++++++++---------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/packages/backend/src/server/api/mastodon/endpoints/account.ts b/packages/backend/src/server/api/mastodon/endpoints/account.ts index 2766dbdce..58de9ad17 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/account.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/account.ts @@ -1,6 +1,4 @@ -import megalodon, { MegalodonInterface } from "@cutls/megalodon"; import Router from "@koa/router"; -import { koaBody } from "koa-body"; import { getClient } from "../ApiMastodonCompatibleService.js"; import { toLimitToInt } from "./timeline.js"; @@ -22,7 +20,7 @@ const relationshopModel = { } export function apiAccountMastodon(router: Router): void { - router.get("/v1/accounts/verify_credentials", async (ctx, next) => { + router.get("/v1/accounts/verify_credentials", async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -67,7 +65,7 @@ export function apiAccountMastodon(router: Router): void { }); router.get<{ Params: { id: string } }>( "/v1/accounts/:id", - async (ctx, next) => { + async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -84,7 +82,7 @@ export function apiAccountMastodon(router: Router): void { ); router.get<{ Params: { id: string } }>( "/v1/accounts/:id/statuses", - async (ctx, next) => { + async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -104,7 +102,7 @@ export function apiAccountMastodon(router: Router): void { ); router.get<{ Params: { id: string } }>( "/v1/accounts/:id/followers", - async (ctx, next) => { + async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -124,7 +122,7 @@ export function apiAccountMastodon(router: Router): void { ); router.get<{ Params: { id: string } }>( "/v1/accounts/:id/following", - async (ctx, next) => { + async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -144,7 +142,7 @@ export function apiAccountMastodon(router: Router): void { ); router.get<{ Params: { id: string } }>( "/v1/accounts/:id/lists", - async (ctx, next) => { + async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -161,7 +159,7 @@ export function apiAccountMastodon(router: Router): void { ); router.post<{ Params: { id: string } }>( "/v1/accounts/:id/follow", - async (ctx, next) => { + async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -180,7 +178,7 @@ export function apiAccountMastodon(router: Router): void { ); router.post<{ Params: { id: string } }>( "/v1/accounts/:id/unfollow", - async (ctx, next) => { + async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -199,7 +197,7 @@ export function apiAccountMastodon(router: Router): void { ); router.post<{ Params: { id: string } }>( "/v1/accounts/:id/block", - async (ctx, next) => { + async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -216,7 +214,7 @@ export function apiAccountMastodon(router: Router): void { ); router.post<{ Params: { id: string } }>( "/v1/accounts/:id/unblock", - async (ctx, next) => { + async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -253,7 +251,7 @@ export function apiAccountMastodon(router: Router): void { ); router.post<{ Params: { id: string } }>( "/v1/accounts/:id/unmute", - async (ctx, next) => { + async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -268,7 +266,7 @@ export function apiAccountMastodon(router: Router): void { } }, ); - router.get("/v1/accounts/relationships", async (ctx, next) => { + router.get("/v1/accounts/relationships", async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -286,7 +284,7 @@ export function apiAccountMastodon(router: Router): void { ctx.body = e.response.data; } }); - router.get("/v1/bookmarks", async (ctx, next) => { + router.get("/v1/bookmarks", async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -300,7 +298,7 @@ export function apiAccountMastodon(router: Router): void { ctx.body = e.response.data; } }); - router.get("/v1/favourites", async (ctx, next) => { + router.get("/v1/favourites", async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -314,7 +312,7 @@ export function apiAccountMastodon(router: Router): void { ctx.body = e.response.data; } }); - router.get("/v1/mutes", async (ctx, next) => { + router.get("/v1/mutes", async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -328,7 +326,7 @@ export function apiAccountMastodon(router: Router): void { ctx.body = e.response.data; } }); - router.get("/v1/blocks", async (ctx, next) => { + router.get("/v1/blocks", async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -342,7 +340,7 @@ export function apiAccountMastodon(router: Router): void { ctx.body = e.response.data; } }); - router.get("/v1/follow_ctxs", async (ctx, next) => { + router.get("/v1/follow_ctxs", async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -360,7 +358,7 @@ export function apiAccountMastodon(router: Router): void { }); router.post<{ Params: { id: string } }>( "/v1/follow_ctxs/:id/authorize", - async (ctx, next) => { + async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -377,7 +375,7 @@ export function apiAccountMastodon(router: Router): void { ); router.post<{ Params: { id: string } }>( "/v1/follow_ctxs/:id/reject", - async (ctx, next) => { + async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); From f5a9add71223460c636655893a0ad0b564731357 Mon Sep 17 00:00:00 2001 From: cutestnekoaqua Date: Sun, 12 Feb 2023 00:10:10 +0100 Subject: [PATCH 11/38] add account lookup --- .../server/api/mastodon/endpoints/account.ts | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/packages/backend/src/server/api/mastodon/endpoints/account.ts b/packages/backend/src/server/api/mastodon/endpoints/account.ts index 58de9ad17..82c721ef4 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/account.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/account.ts @@ -63,6 +63,31 @@ export function apiAccountMastodon(router: Router): void { ctx.body = e.response.data; } }); + router.get( + "/v1/accounts/lookup", + async (ctx) => { + const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; + const accessTokens = ctx.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const data = await client.searchAccount((ctx.query.acct || '').toString(), { + resolve: true + }); + ctx.body = data.data[0]; + if (data.data.length === 0) { + ctx.status = 404; + ctx.body = { + error: "Record not found" + } + } + } catch (e: any) { + console.error(e); + console.error(e.response.data); + ctx.status = 401; + ctx.body = e.response.data; + } + }, + ); router.get<{ Params: { id: string } }>( "/v1/accounts/:id", async (ctx) => { From d91358ce2f3a037929331cb534888bfcf7a3dc62 Mon Sep 17 00:00:00 2001 From: cutestnekoaqua Date: Sun, 12 Feb 2023 00:14:03 +0100 Subject: [PATCH 12/38] refine error msg --- packages/backend/src/server/api/mastodon/endpoints/account.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/server/api/mastodon/endpoints/account.ts b/packages/backend/src/server/api/mastodon/endpoints/account.ts index 82c721ef4..cb9f6c4ef 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/account.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/account.ts @@ -77,7 +77,7 @@ export function apiAccountMastodon(router: Router): void { if (data.data.length === 0) { ctx.status = 404; ctx.body = { - error: "Record not found" + error: `Record (${ctx.query.acct}) not found` } } } catch (e: any) { From 1acf0518b024f083efb99b5b60e095fbf2c895a3 Mon Sep 17 00:00:00 2001 From: cutestnekoaqua Date: Sun, 12 Feb 2023 00:19:35 +0100 Subject: [PATCH 13/38] try this instead --- .../backend/src/server/api/mastodon/endpoints/account.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/backend/src/server/api/mastodon/endpoints/account.ts b/packages/backend/src/server/api/mastodon/endpoints/account.ts index cb9f6c4ef..fe48e4a11 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/account.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/account.ts @@ -70,11 +70,11 @@ export function apiAccountMastodon(router: Router): void { const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); try { - const data = await client.searchAccount((ctx.query.acct || '').toString(), { + const data = await client.search((ctx.query.acct || '').toString(), "accounts", { resolve: true }); - ctx.body = data.data[0]; - if (data.data.length === 0) { + ctx.body = data.data.accounts[0]; + if (data.data.accounts.length === 0) { ctx.status = 404; ctx.body = { error: `Record (${ctx.query.acct}) not found` From a97806eeaab4091e2c9491aec2b246c33fd758de Mon Sep 17 00:00:00 2001 From: cutestnekoaqua Date: Sun, 12 Feb 2023 00:25:51 +0100 Subject: [PATCH 14/38] simplify code --- .../server/api/mastodon/endpoints/account.ts | 33 ++++--------------- 1 file changed, 7 insertions(+), 26 deletions(-) diff --git a/packages/backend/src/server/api/mastodon/endpoints/account.ts b/packages/backend/src/server/api/mastodon/endpoints/account.ts index fe48e4a11..4e2c93334 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/account.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/account.ts @@ -63,39 +63,20 @@ export function apiAccountMastodon(router: Router): void { ctx.body = e.response.data; } }); - router.get( - "/v1/accounts/lookup", - async (ctx) => { - const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; - const accessTokens = ctx.headers.authorization; - const client = getClient(BASE_URL, accessTokens); - try { - const data = await client.search((ctx.query.acct || '').toString(), "accounts", { - resolve: true - }); - ctx.body = data.data.accounts[0]; - if (data.data.accounts.length === 0) { - ctx.status = 404; - ctx.body = { - error: `Record (${ctx.query.acct}) not found` - } - } - } catch (e: any) { - console.error(e); - console.error(e.response.data); - ctx.status = 401; - ctx.body = e.response.data; - } - }, - ); router.get<{ Params: { id: string } }>( "/v1/accounts/:id", async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); + let req_user = ctx.query.acct; + if (!req_user) { + req_user = ctx.params.id; + } else { + req_user = req_user.toString(); + } try { - const data = await client.getAccount(ctx.params.id); + const data = await client.getAccount(req_user); ctx.body = data.data; } catch (e: any) { console.error(e); From b2bb9ec178933ca51b68e539ad8040b3102e81d0 Mon Sep 17 00:00:00 2001 From: cutestnekoaqua Date: Sun, 12 Feb 2023 00:29:52 +0100 Subject: [PATCH 15/38] eow --- .../server/api/mastodon/endpoints/account.ts | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/packages/backend/src/server/api/mastodon/endpoints/account.ts b/packages/backend/src/server/api/mastodon/endpoints/account.ts index 4e2c93334..2836c7fda 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/account.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/account.ts @@ -63,20 +63,31 @@ export function apiAccountMastodon(router: Router): void { ctx.body = e.response.data; } }); + router.get( + "/v1/accounts/lookup", + async (ctx) => { + const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; + const accessTokens = ctx.headers.authorization; + const client = getClient(BASE_URL, accessTokens); + try { + const data = await client.getAccount(( || '').toString()); + ctx.body = data.data; + } catch (e: any) { + console.error(e); + console.error(e.response.data); + ctx.status = 401; + ctx.body = e.response.data; + } + }, + ); router.get<{ Params: { id: string } }>( "/v1/accounts/:id", async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); - let req_user = ctx.query.acct; - if (!req_user) { - req_user = ctx.params.id; - } else { - req_user = req_user.toString(); - } try { - const data = await client.getAccount(req_user); + const data = await client.getAccount(ctx.params.id); ctx.body = data.data; } catch (e: any) { console.error(e); From 740e5e56bac426cf8dd38f562f9b5f87c809ad28 Mon Sep 17 00:00:00 2001 From: cutestnekoaqua Date: Sun, 12 Feb 2023 00:33:52 +0100 Subject: [PATCH 16/38] oof --- packages/backend/src/server/api/mastodon/endpoints/account.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/server/api/mastodon/endpoints/account.ts b/packages/backend/src/server/api/mastodon/endpoints/account.ts index 2836c7fda..ef9ac4f43 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/account.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/account.ts @@ -70,7 +70,7 @@ export function apiAccountMastodon(router: Router): void { const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); try { - const data = await client.getAccount(( || '').toString()); + const data = await client.getAccount((ctx.query.acct || '').toString()); ctx.body = data.data; } catch (e: any) { console.error(e); From 8149145b75333abd0988a9dec263b19f47680082 Mon Sep 17 00:00:00 2001 From: cutestnekoaqua Date: Sun, 12 Feb 2023 00:35:39 +0100 Subject: [PATCH 17/38] is this too spec? --- packages/backend/src/server/api/mastodon/endpoints/account.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/server/api/mastodon/endpoints/account.ts b/packages/backend/src/server/api/mastodon/endpoints/account.ts index ef9ac4f43..1127fa5fb 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/account.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/account.ts @@ -70,7 +70,7 @@ export function apiAccountMastodon(router: Router): void { const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); try { - const data = await client.getAccount((ctx.query.acct || '').toString()); + const data = await client.getAccount(`@${(ctx.query.acct || '').toString()}`); ctx.body = data.data; } catch (e: any) { console.error(e); From 6333016077ccf080ae2983ffabea295b6c4bd471 Mon Sep 17 00:00:00 2001 From: ThatOneCalculator Date: Sat, 11 Feb 2023 16:20:57 -0800 Subject: [PATCH 18/38] chore: calckey megalodon --- packages/backend/package.json | 2 +- pnpm-lock.yaml | 52 +++++++++++++++++------------------ 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index c1af9b173..55a64191a 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -79,7 +79,7 @@ "koa-send": "5.0.1", "koa-slow": "2.1.0", "koa-views": "7.0.2", - "@cutls/megalodon": "5.1.15", + "@calckey/megalodon": "5.1.2", "mfm-js": "0.23.2", "mime-types": "2.1.35", "multer": "1.4.4-lts.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 056b02cbf..827dc8da5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -57,7 +57,7 @@ importers: '@bull-board/api': ^4.6.4 '@bull-board/koa': ^4.6.4 '@bull-board/ui': ^4.6.4 - '@cutls/megalodon': 5.1.15 + '@calckey/megalodon': 5.1.2 '@discordapp/twemoji': 14.0.2 '@elastic/elasticsearch': 7.17.0 '@koa/cors': 3.4.3 @@ -223,7 +223,7 @@ importers: '@bull-board/api': 4.10.2 '@bull-board/koa': 4.10.2_6tybghmia4wsnt33xeid7y4rby '@bull-board/ui': 4.10.2 - '@cutls/megalodon': 5.1.15 + '@calckey/megalodon': 5.1.2 '@discordapp/twemoji': 14.0.2 '@elastic/elasticsearch': 7.17.0 '@koa/cors': 3.4.3 @@ -746,6 +746,30 @@ packages: '@bull-board/api': 4.10.2 dev: false + /@calckey/megalodon/5.1.2: + resolution: {integrity: sha512-bUjPOfASy8X2NxdBvYDOWN9Rw/KdkfbTxy5vMQBcrGXepFbT4M+00blEYNc00Uu/epwH9YoNqpQC8PKQr/WU4w==} + engines: {node: '>=15.0.0'} + dependencies: + '@types/oauth': 0.9.1 + '@types/ws': 8.5.4 + axios: 1.2.2 + dayjs: 1.11.7 + form-data: 4.0.0 + https-proxy-agent: 5.0.1 + oauth: 0.10.0 + object-assign-deep: 0.4.0 + parse-link-header: 2.0.0 + socks-proxy-agent: 7.0.0 + typescript: 4.9.4 + uuid: 9.0.0 + ws: 8.12.0 + transitivePeerDependencies: + - bufferutil + - debug + - supports-color + - utf-8-validate + dev: false + /@colors/colors/1.5.0: resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} engines: {node: '>=0.1.90'} @@ -847,30 +871,6 @@ packages: dependencies: '@jridgewell/trace-mapping': 0.3.9 - /@cutls/megalodon/5.1.15: - resolution: {integrity: sha512-4+mIKUYYr2CLY3idSxXk56WSTG9ww3opeenmsPRxftTwcjQTYxGntNkWmJWEbzeJ4rPslnvpwD7cFR62bPf41g==} - engines: {node: '>=15.0.0'} - dependencies: - '@types/oauth': 0.9.1 - '@types/ws': 8.5.4 - axios: 1.2.2 - dayjs: 1.11.7 - form-data: 4.0.0 - https-proxy-agent: 5.0.1 - oauth: 0.10.0 - object-assign-deep: 0.4.0 - parse-link-header: 2.0.0 - socks-proxy-agent: 7.0.0 - typescript: 4.9.4 - uuid: 9.0.0 - ws: 8.12.0 - transitivePeerDependencies: - - bufferutil - - debug - - supports-color - - utf-8-validate - dev: false - /@cypress/request/2.88.11: resolution: {integrity: sha512-M83/wfQ1EkspjkE2lNWNV5ui2Cv7UCv1swW1DqljahbzLVWltcsexQh8jYtuS/vzFXP+HySntGM83ZXA9fn17w==} engines: {node: '>= 6'} From 07ca57574f302196c8080df3f879687f269cf482 Mon Sep 17 00:00:00 2001 From: Free Date: Sun, 12 Feb 2023 01:11:11 +0000 Subject: [PATCH 19/38] Hide inactive tab labels on mobile (#9609) Co-authored-by: Freeplay Reviewed-on: https://codeberg.org/calckey/calckey/pulls/9609 Co-authored-by: Free Co-committed-by: Free --- .../src/components/global/MkPageHeader.vue | 704 +++++++++--------- 1 file changed, 359 insertions(+), 345 deletions(-) diff --git a/packages/client/src/components/global/MkPageHeader.vue b/packages/client/src/components/global/MkPageHeader.vue index 464a965b3..c6568bbff 100644 --- a/packages/client/src/components/global/MkPageHeader.vue +++ b/packages/client/src/components/global/MkPageHeader.vue @@ -1,247 +1,314 @@ - + - - From 9f3c9f886896a193880873f297dbd6f05d112a02 Mon Sep 17 00:00:00 2001 From: ThatOneCalculator Date: Sat, 11 Feb 2023 17:14:50 -0800 Subject: [PATCH 20/38] Formatting --- .gitignore | 2 + .../src/components/global/MkPageHeader.vue | 659 +++++++++--------- 2 files changed, 331 insertions(+), 330 deletions(-) diff --git a/.gitignore b/.gitignore index 135bf9660..52139614c 100644 --- a/.gitignore +++ b/.gitignore @@ -42,6 +42,8 @@ api-docs.json files ormconfig.json packages/backend/assets/instance.css +packages/backend/assets/sounds/None.mp3 + # blender backups *.blend1 diff --git a/packages/client/src/components/global/MkPageHeader.vue b/packages/client/src/components/global/MkPageHeader.vue index c6568bbff..f37b2f43f 100644 --- a/packages/client/src/components/global/MkPageHeader.vue +++ b/packages/client/src/components/global/MkPageHeader.vue @@ -7,7 +7,7 @@
- +
{{ metadata.title }}
@@ -31,284 +31,226 @@
- + - + From 8c45c5fc5b933962ebf9b420c42a68656c241d6d Mon Sep 17 00:00:00 2001 From: ThatOneCalculator Date: Sat, 11 Feb 2023 17:16:55 -0800 Subject: [PATCH 21/38] chore: tag dev1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 18df3e5b2..4a5222f61 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "calckey", - "version": "13.2.0-dev", + "version": "13.2.0-dev1", "codename": "aqua", "repository": { "type": "git", From 7091f889ee27c44f2680fc4518917656729591af Mon Sep 17 00:00:00 2001 From: Kaity A Date: Sun, 12 Feb 2023 01:19:43 +0000 Subject: [PATCH 22/38] Enable reply update/display in detailed view. (#9606) This PR establishes a new replied note stream update for subscribed notes, which gets fired off whenever a note receives a reply and the user is subscribed to the note for updates. It specifically does not provide note details as part of the update, just the note id of the reply, so that they must go and retrieve the note and be subject to the proper permission and visibility checks. The detailed note component has then been updated to watch for the replied notification so it can add new replies to the thread as they are created. This allows both seeing new replies while on the page, and also to see your own replies appear after you post them without having to reload the page. This PR relies on https://codeberg.org/calckey/calckey.js/pulls/2 to add the replied type to the calkey.js module. Co-authored-by: Kaity A Reviewed-on: https://codeberg.org/calckey/calckey/pulls/9606 Co-authored-by: Kaity A Co-committed-by: Kaity A --- .../backend/src/server/api/stream/types.ts | 3 +++ packages/backend/src/services/note/create.ts | 8 +++++- .../client/src/components/MkNoteDetailed.vue | 27 +++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/packages/backend/src/server/api/stream/types.ts b/packages/backend/src/server/api/stream/types.ts index 837f42c87..b35c599bd 100644 --- a/packages/backend/src/server/api/stream/types.ts +++ b/packages/backend/src/server/api/stream/types.ts @@ -135,6 +135,9 @@ export interface NoteStreamTypes { reaction: string; userId: User["id"]; }; + replied: { + id: Note["id"]; + }; } type NoteStreamEventTypes = { [key in keyof NoteStreamTypes]: { diff --git a/packages/backend/src/services/note/create.ts b/packages/backend/src/services/note/create.ts index 210ea7771..b37b160fb 100644 --- a/packages/backend/src/services/note/create.ts +++ b/packages/backend/src/services/note/create.ts @@ -1,6 +1,6 @@ import * as mfm from "mfm-js"; import es from "../../db/elasticsearch.js"; -import { publishMainStream, publishNotesStream } from "@/services/stream.js"; +import { publishMainStream, publishNotesStream, publishNoteStream } from "@/services/stream.js"; import DeliverManager from "@/remote/activitypub/deliver-manager.js"; import renderNote from "@/remote/activitypub/renderer/note.js"; import renderCreate from "@/remote/activitypub/renderer/create.js"; @@ -430,6 +430,12 @@ export default async ( } publishNotesStream(note); + if (note.replyId != null) { + // Only provide the reply note id here as the recipient may not be authorized to see the note. + publishNoteStream(note.replyId, "replied", { + id: note.id, + }); + } const webhooks = await getActiveWebhooks().then((webhooks) => webhooks.filter((x) => x.userId === user.id && x.on.includes("note")), diff --git a/packages/client/src/components/MkNoteDetailed.vue b/packages/client/src/components/MkNoteDetailed.vue index dd6187d7e..fab06f1ab 100644 --- a/packages/client/src/components/MkNoteDetailed.vue +++ b/packages/client/src/components/MkNoteDetailed.vue @@ -142,6 +142,8 @@ import { i18n } from '@/i18n'; import { getNoteMenu } from '@/scripts/get-note-menu'; import { useNoteCapture } from '@/scripts/use-note-capture'; import { deepClone } from '@/scripts/clone'; +import { stream } from '@/stream'; +import { NoteUpdatedEvent } from 'calckey-js/built/streaming.types'; const router = useRouter(); @@ -302,6 +304,31 @@ if (appearNote.replyId) { conversation.value = res.reverse(); }); } + +function onNoteReplied(noteData: NoteUpdatedEvent): void { + const { type, id, body } = noteData; + if (type === 'replied' && id === appearNote.id) { + const { id: createdId } = body; + + os.api('notes/show', { + noteId: createdId, + }).then(note => { + if (note.replyId === appearNote.id) { + replies.value.unshift(note); + directReplies.value.unshift(note); + } + }); + } + +} + +onMounted(() => { + stream.on("noteUpdated", onNoteReplied); +}); + +onUnmounted(() => { + stream.off("noteUpdated", onNoteReplied); +}); diff --git a/packages/client/src/os.ts b/packages/client/src/os.ts index 0784b68de..a0c263572 100644 --- a/packages/client/src/os.ts +++ b/packages/client/src/os.ts @@ -545,6 +545,21 @@ export async function selectUser() { }); } +export async function selectInstance(): Promise { + return new Promise((resolve, reject) => { + popup( + defineAsyncComponent(() => import("@/components/MkInstanceSelectDialog.vue")), + {}, + { + ok: (instance) => { + resolve(instance); + }, + }, + "closed", + ); + }); +} + export async function selectDriveFile(multiple: boolean) { return new Promise((resolve, reject) => { popup( diff --git a/packages/client/src/pages/my-antennas/create.vue b/packages/client/src/pages/my-antennas/create.vue index 794b74370..337816e00 100644 --- a/packages/client/src/pages/my-antennas/create.vue +++ b/packages/client/src/pages/my-antennas/create.vue @@ -5,7 +5,6 @@