From 60f7e2cf6a71eb02a174e067e88d18c22ac41c22 Mon Sep 17 00:00:00 2001 From: Pyrox Date: Mon, 27 Nov 2023 18:17:34 -0500 Subject: [PATCH] [feat] Remove Twitter Integration --- ...701069578019-remove-twitter-integration.ts | 29 + packages/backend/src/models/entities/meta.ts | 17 - .../src/remote/activitypub/models/person.ts | 4 - .../src/server/api/endpoints/admin/meta.ts | 44 -- .../server/api/endpoints/admin/update-meta.ts | 14 - .../backend/src/server/api/endpoints/meta.ts | 12 - packages/backend/src/server/api/index.ts | 3 - .../backend/src/server/api/service/twitter.ts | 226 ------ packages/backend/src/server/nodeinfo.ts | 1 - .../backend/src/server/web/views/clip.pug | 4 - .../src/server/web/views/gallery-post.pug | 4 - .../backend/src/server/web/views/note.pug | 4 - .../backend/src/server/web/views/page.pug | 4 - .../backend/src/server/web/views/user.pug | 3 - packages/client/src/components/MkSignin.vue | 669 +++++++++--------- .../client/src/pages/admin/integrations.vue | 2 - .../client/src/pages/settings/integration.vue | 53 +- .../iceshrimp-js/etc/iceshrimp-js.api.json | 2 +- packages/iceshrimp-js/etc/iceshrimp-js.api.md | 1 - packages/iceshrimp-js/etc/misskey-js.api.md | 1 - ...shrimp-js.entities.liteinstancemetadata.md | 1 - packages/iceshrimp-js/src/entities.ts | 1 - 22 files changed, 370 insertions(+), 729 deletions(-) create mode 100644 packages/backend/src/migration/1701069578019-remove-twitter-integration.ts delete mode 100644 packages/backend/src/server/api/service/twitter.ts diff --git a/packages/backend/src/migration/1701069578019-remove-twitter-integration.ts b/packages/backend/src/migration/1701069578019-remove-twitter-integration.ts new file mode 100644 index 000000000..f010162d0 --- /dev/null +++ b/packages/backend/src/migration/1701069578019-remove-twitter-integration.ts @@ -0,0 +1,29 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class RemoveTwitterIntegration1701069578019 implements MigrationInterface { + name = "RemoveTwitterIntegration1701069578019"; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "meta" DROP COLUMN IF EXISTS "enableTwitterIntegration"`, + ); + await queryRunner.query( + `ALTER TABLE "meta" DROP COLUMN IF EXISTS "twitterConsumerKey"`, + ); + await queryRunner.query( + `ALTER TABLE "meta" DROP COLUMN IF EXISTS "twitterConsumerSecret"`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "meta" ADD COLUMN IF NOT EXISTS "enableTwitterIntegration" boolean NOT NULL DEFAULT false`, + ); + await queryRunner.query( + `ALTER TABLE "meta" ADD COLUMN IF NOT EXISTS "twitterConsumerKey" character varying(128)`, + ); + await queryRunner.query( + `ALTER TABLE "meta" ADD COLUMN IF NOT EXISTS "twitterConsumerSecret" character varying(128)`, + ); + } +} diff --git a/packages/backend/src/models/entities/meta.ts b/packages/backend/src/models/entities/meta.ts index 4f5bff08c..dfebad853 100644 --- a/packages/backend/src/models/entities/meta.ts +++ b/packages/backend/src/models/entities/meta.ts @@ -310,23 +310,6 @@ export class Meta { }) public swPrivateKey: string; - @Column("boolean", { - default: false, - }) - public enableTwitterIntegration: boolean; - - @Column("varchar", { - length: 128, - nullable: true, - }) - public twitterConsumerKey: string | null; - - @Column("varchar", { - length: 128, - nullable: true, - }) - public twitterConsumerSecret: string | null; - @Column("boolean", { default: false, }) diff --git a/packages/backend/src/remote/activitypub/models/person.ts b/packages/backend/src/remote/activitypub/models/person.ts index fe2887d02..dc2670c4c 100644 --- a/packages/backend/src/remote/activitypub/models/person.ts +++ b/packages/backend/src/remote/activitypub/models/person.ts @@ -687,10 +687,6 @@ export async function resolvePerson( const services: { [x: string]: (id: string, username: string) => any; } = { - "misskey:authentication:twitter": (userId, screenName) => ({ - userId, - screenName, - }), "misskey:authentication:github": (id, login) => ({ id, login }), "misskey:authentication:discord": (id, name) => $discord(id, name), }; diff --git a/packages/backend/src/server/api/endpoints/admin/meta.ts b/packages/backend/src/server/api/endpoints/admin/meta.ts index c3177fc1c..4a5a4eea6 100644 --- a/packages/backend/src/server/api/endpoints/admin/meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/meta.ts @@ -140,11 +140,6 @@ export const meta = { optional: false, nullable: false, }, - enableTwitterIntegration: { - type: "boolean", - optional: false, - nullable: false, - }, enableGithubIntegration: { type: "boolean", optional: false, @@ -260,36 +255,6 @@ export const meta = { optional: true, nullable: true, }, - twitterConsumerKey: { - type: "string", - optional: true, - nullable: true, - }, - twitterConsumerSecret: { - type: "string", - optional: true, - nullable: true, - }, - githubClientId: { - type: "string", - optional: true, - nullable: true, - }, - githubClientSecret: { - type: "string", - optional: true, - nullable: true, - }, - discordClientId: { - type: "string", - optional: true, - nullable: true, - }, - discordClientSecret: { - type: "string", - optional: true, - nullable: true, - }, summaryProxy: { type: "string", optional: true, @@ -483,9 +448,6 @@ export default define(meta, paramDef, async (ps, me) => { defaultLightTheme: instance.defaultLightTheme, defaultDarkTheme: instance.defaultDarkTheme, enableEmail: instance.enableEmail, - enableTwitterIntegration: instance.enableTwitterIntegration, - enableGithubIntegration: instance.enableGithubIntegration, - enableDiscordIntegration: instance.enableDiscordIntegration, translatorAvailable: instance.deeplAuthKey != null || instance.libreTranslateApiUrl != null, pinnedPages: instance.pinnedPages, @@ -504,12 +466,6 @@ export default define(meta, paramDef, async (ps, me) => { secureMode: instance.secureMode, hcaptchaSecretKey: instance.hcaptchaSecretKey, recaptchaSecretKey: instance.recaptchaSecretKey, - twitterConsumerKey: instance.twitterConsumerKey, - twitterConsumerSecret: instance.twitterConsumerSecret, - githubClientId: instance.githubClientId, - githubClientSecret: instance.githubClientSecret, - discordClientId: instance.discordClientId, - discordClientSecret: instance.discordClientSecret, summalyProxy: instance.summalyProxy, email: instance.email, smtpSecure: instance.smtpSecure, 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 7f0c279ce..32276783a 100644 --- a/packages/backend/src/server/api/endpoints/admin/update-meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/update-meta.ts @@ -124,9 +124,6 @@ export const paramDef = { deeplIsPro: { type: "boolean" }, libreTranslateApiUrl: { type: "string", nullable: true }, libreTranslateApiKey: { type: "string", nullable: true }, - enableTwitterIntegration: { type: "boolean" }, - twitterConsumerKey: { type: "string", nullable: true }, - twitterConsumerSecret: { type: "string", nullable: true }, enableGithubIntegration: { type: "boolean" }, githubClientId: { type: "string", nullable: true }, githubClientSecret: { type: "string", nullable: true }, @@ -363,17 +360,6 @@ export default define(meta, paramDef, async (ps, me) => { set.summalyProxy = ps.summalyProxy; } - if (ps.enableTwitterIntegration !== undefined) { - set.enableTwitterIntegration = ps.enableTwitterIntegration; - } - - if (ps.twitterConsumerKey !== undefined) { - set.twitterConsumerKey = ps.twitterConsumerKey; - } - - if (ps.twitterConsumerSecret !== undefined) { - set.twitterConsumerSecret = ps.twitterConsumerSecret; - } if (ps.enableGithubIntegration !== undefined) { set.enableGithubIntegration = ps.enableGithubIntegration; diff --git a/packages/backend/src/server/api/endpoints/meta.ts b/packages/backend/src/server/api/endpoints/meta.ts index bab32b73c..834562dae 100644 --- a/packages/backend/src/server/api/endpoints/meta.ts +++ b/packages/backend/src/server/api/endpoints/meta.ts @@ -251,11 +251,6 @@ export const meta = { optional: false, nullable: false, }, - enableTwitterIntegration: { - type: "boolean", - optional: false, - nullable: false, - }, enableGithubIntegration: { type: "boolean", optional: false, @@ -320,11 +315,6 @@ export const meta = { optional: false, nullable: false, }, - twitter: { - type: "boolean", - optional: false, - nullable: false, - }, github: { type: "boolean", optional: false, @@ -453,7 +443,6 @@ export default define(meta, paramDef, async (ps, me) => { enableEmail: instance.enableEmail, - enableTwitterIntegration: instance.enableTwitterIntegration, enableGithubIntegration: instance.enableGithubIntegration, enableDiscordIntegration: instance.enableDiscordIntegration, @@ -487,7 +476,6 @@ export default define(meta, paramDef, async (ps, me) => { hcaptcha: instance.enableHcaptcha, recaptcha: instance.enableRecaptcha, objectStorage: instance.useObjectStorage, - twitter: instance.enableTwitterIntegration, github: instance.enableGithubIntegration, discord: instance.enableDiscordIntegration, serviceWorker: true, diff --git a/packages/backend/src/server/api/index.ts b/packages/backend/src/server/api/index.ts index e3535ae39..3d09d4d40 100644 --- a/packages/backend/src/server/api/index.ts +++ b/packages/backend/src/server/api/index.ts @@ -19,7 +19,6 @@ import signupPending from "./private/signup-pending.js"; import verifyEmail from "./private/verify-email.js"; import discord from "./service/discord.js"; import github from "./service/github.js"; -import twitter from "./service/twitter.js"; // Init app const app = new Koa(); @@ -112,8 +111,6 @@ router.post("/verify-email", verifyEmail); router.use(discord.routes()); router.use(github.routes()); -router.use(twitter.routes()); - router.post("/miauth/:session/check", async (ctx) => { const token = await AccessTokens.findOneBy({ session: ctx.params.session, diff --git a/packages/backend/src/server/api/service/twitter.ts b/packages/backend/src/server/api/service/twitter.ts deleted file mode 100644 index 369559241..000000000 --- a/packages/backend/src/server/api/service/twitter.ts +++ /dev/null @@ -1,226 +0,0 @@ -import type Koa from "koa"; -import Router from "@koa/router"; -import { v4 as uuid } from "uuid"; -import autwh from "autwh"; -import { IsNull } from "typeorm"; -import { publishMainStream } from "@/services/stream.js"; -import config from "@/config/index.js"; -import { fetchMeta } from "@/misc/fetch-meta.js"; -import { Users, UserProfiles } from "@/models/index.js"; -import type { ILocalUser } from "@/models/entities/user.js"; -import signin from "../common/signin.js"; -import { redisClient } from "../../../db/redis.js"; - -function getUserToken(ctx: Koa.BaseContext): string | null { - return ((ctx.headers["cookie"] || "").match(/igi=(\w+)/) || [null, null])[1]; -} - -function compareOrigin(ctx: Koa.BaseContext): boolean { - function normalizeUrl(url?: string): string { - return url == null - ? "" - : url.endsWith("/") - ? url.substr(0, url.length - 1) - : url; - } - - const referer = ctx.headers["referer"]; - - return normalizeUrl(referer) === normalizeUrl(config.url); -} - -// Init router -const router = new Router(); - -router.get("/disconnect/twitter", async (ctx) => { - if (!compareOrigin(ctx)) { - ctx.throw(400, "invalid origin"); - return; - } - - const userToken = getUserToken(ctx); - if (userToken == null) { - ctx.throw(400, "signin required"); - return; - } - - const user = await Users.findOneByOrFail({ - host: IsNull(), - token: userToken, - }); - - const profile = await UserProfiles.findOneByOrFail({ userId: user.id }); - - profile.integrations.twitter = undefined; - - await UserProfiles.update(user.id, { - integrations: profile.integrations, - }); - - ctx.body = "Twitterの連携を解除しました :v:"; - - // Publish i updated event - publishMainStream( - user.id, - "meUpdated", - await Users.pack(user, user, { - detail: true, - includeSecrets: true, - }), - ); -}); - -async function getTwAuth() { - const meta = await fetchMeta(true); - - if ( - meta.enableTwitterIntegration && - meta.twitterConsumerKey && - meta.twitterConsumerSecret - ) { - return autwh({ - consumerKey: meta.twitterConsumerKey, - consumerSecret: meta.twitterConsumerSecret, - callbackUrl: `${config.url}/api/tw/cb`, - }); - } else { - return null; - } -} - -router.get("/connect/twitter", async (ctx) => { - if (!compareOrigin(ctx)) { - ctx.throw(400, "invalid origin"); - return; - } - - const userToken = getUserToken(ctx); - if (userToken == null) { - ctx.throw(400, "signin required"); - return; - } - - const twAuth = await getTwAuth(); - const twCtx = await twAuth!.begin(); - redisClient.set(userToken, JSON.stringify(twCtx)); - ctx.redirect(twCtx.url); -}); - -router.get("/signin/twitter", async (ctx) => { - const twAuth = await getTwAuth(); - const twCtx = await twAuth!.begin(); - - const sessid = uuid(); - - redisClient.set(sessid, JSON.stringify(twCtx)); - - ctx.cookies.set("signin_with_twitter_sid", sessid, { - path: "/", - secure: config.url.startsWith("https"), - httpOnly: true, - }); - - ctx.redirect(twCtx.url); -}); - -router.get("/tw/cb", async (ctx) => { - const userToken = getUserToken(ctx); - - const twAuth = await getTwAuth(); - - if (userToken == null) { - const sessid = ctx.cookies.get("signin_with_twitter_sid"); - - if (sessid == null) { - ctx.throw(400, "invalid session"); - return; - } - - const get = new Promise((res, rej) => { - redisClient.get(sessid, async (_, twCtx) => { - res(twCtx); - }); - }); - - const twCtx = await get; - - const verifier = ctx.query.oauth_verifier; - if (!verifier || typeof verifier !== "string") { - ctx.throw(400, "invalid session"); - return; - } - - const result = await twAuth!.done(JSON.parse(twCtx), verifier); - - const link = await UserProfiles.createQueryBuilder() - .where("\"integrations\"->'twitter'->>'userId' = :id", { - id: result.userId, - }) - .andWhere('"userHost" IS NULL') - .getOne(); - - if (link == null) { - ctx.throw( - 404, - `@${result.screenName}と連携しているMisskeyアカウントはありませんでした...`, - ); - return; - } - - signin( - ctx, - (await Users.findOneBy({ id: link.userId })) as ILocalUser, - true, - ); - } else { - const verifier = ctx.query.oauth_verifier; - - if (!verifier || typeof verifier !== "string") { - ctx.throw(400, "invalid session"); - return; - } - - const get = new Promise((res, rej) => { - redisClient.get(userToken, async (_, twCtx) => { - res(twCtx); - }); - }); - - const twCtx = await get; - - const result = await twAuth!.done(JSON.parse(twCtx), verifier); - - const user = await Users.findOneByOrFail({ - host: IsNull(), - token: userToken, - }); - - const profile = await UserProfiles.findOneByOrFail({ userId: user.id }); - - await UserProfiles.update(user.id, { - integrations: { - ...profile.integrations, - twitter: { - accessToken: result.accessToken, - accessTokenSecret: result.accessTokenSecret, - userId: result.userId, - screenName: result.screenName, - }, - }, - }); - - ctx.body = `Twitter: @${result.screenName} を、Misskey: @${user.username} に接続しました!`; - - // Publish i updated event - publishMainStream( - user.id, - "meUpdated", - await Users.pack(user, user, { - detail: true, - includeSecrets: true, - }), - ); - } -}); - -export default router; diff --git a/packages/backend/src/server/nodeinfo.ts b/packages/backend/src/server/nodeinfo.ts index d51504ff8..65fe5a3f4 100644 --- a/packages/backend/src/server/nodeinfo.ts +++ b/packages/backend/src/server/nodeinfo.ts @@ -84,7 +84,6 @@ const nodeinfo2 = async () => { enableRecaptcha: meta.enableRecaptcha, maxNoteTextLength: MAX_NOTE_TEXT_LENGTH, maxCaptionTextLength: MAX_CAPTION_TEXT_LENGTH, - enableTwitterIntegration: meta.enableTwitterIntegration, enableGithubIntegration: meta.enableGithubIntegration, enableDiscordIntegration: meta.enableDiscordIntegration, enableEmail: meta.enableEmail, diff --git a/packages/backend/src/server/web/views/clip.pug b/packages/backend/src/server/web/views/clip.pug index 79d629380..de7a2373f 100644 --- a/packages/backend/src/server/web/views/clip.pug +++ b/packages/backend/src/server/web/views/clip.pug @@ -31,7 +31,3 @@ block meta meta(name='misskey:user-username' content=user.username) meta(name='misskey:user-id' content=user.id) meta(name='misskey:clip-id' content=clip.id) - - // todo - if user.twitter - meta(name='twitter:creator' content=`@${user.twitter.screenName}`) diff --git a/packages/backend/src/server/web/views/gallery-post.pug b/packages/backend/src/server/web/views/gallery-post.pug index 561a19b25..698309805 100644 --- a/packages/backend/src/server/web/views/gallery-post.pug +++ b/packages/backend/src/server/web/views/gallery-post.pug @@ -31,9 +31,5 @@ block meta meta(name='misskey:user-username' content=user.username) meta(name='misskey:user-id' content=user.id) - // todo - if user.twitter - meta(name='twitter:creator' content=`@${user.twitter.screenName}`) - if !user.host link(rel='alternate' href=url type='application/activity+json') diff --git a/packages/backend/src/server/web/views/note.pug b/packages/backend/src/server/web/views/note.pug index dae0a82d5..300cd2f9c 100644 --- a/packages/backend/src/server/web/views/note.pug +++ b/packages/backend/src/server/web/views/note.pug @@ -44,10 +44,6 @@ block meta meta(name='misskey:user-id' content=user.id) meta(name='misskey:note-id' content=note.id) - // todo - if user.twitter - meta(name='twitter:creator' content=`@${user.twitter.screenName}`) - if note.prev link(rel='prev' href=`${config.url}/notes/${note.prev}`) if note.next diff --git a/packages/backend/src/server/web/views/page.pug b/packages/backend/src/server/web/views/page.pug index bfc7ebf79..87d8ac3b8 100644 --- a/packages/backend/src/server/web/views/page.pug +++ b/packages/backend/src/server/web/views/page.pug @@ -31,7 +31,3 @@ block meta meta(name='misskey:user-username' content=user.username) meta(name='misskey:user-id' content=user.id) meta(name='misskey:page-id' content=page.id) - - // todo - if user.twitter - meta(name='twitter:creator' content=`@${user.twitter.screenName}`) diff --git a/packages/backend/src/server/web/views/user.pug b/packages/backend/src/server/web/views/user.pug index f5820f55f..7c3c2ca18 100644 --- a/packages/backend/src/server/web/views/user.pug +++ b/packages/backend/src/server/web/views/user.pug @@ -31,9 +31,6 @@ block meta meta(name='misskey:user-username' content=user.username) meta(name='misskey:user-id' content=user.id) - if profile.twitter - meta(name='twitter:creator' content=`@${profile.twitter.screenName}`) - if !sub if !user.host link(rel='alternate' href=`${config.url}/users/${user.id}` type='application/activity+json') diff --git a/packages/client/src/components/MkSignin.vue b/packages/client/src/components/MkSignin.vue index dc49ca23d..7511c4d78 100644 --- a/packages/client/src/components/MkSignin.vue +++ b/packages/client/src/components/MkSignin.vue @@ -1,162 +1,153 @@ diff --git a/packages/client/src/pages/admin/integrations.vue b/packages/client/src/pages/admin/integrations.vue index 510b32a08..895808f28 100644 --- a/packages/client/src/pages/admin/integrations.vue +++ b/packages/client/src/pages/admin/integrations.vue @@ -47,13 +47,11 @@ import * as os from "@/os"; import { i18n } from "@/i18n"; import { definePageMetadata } from "@/scripts/page-metadata"; -let enableTwitterIntegration: boolean = $ref(false); let enableGithubIntegration: boolean = $ref(false); let enableDiscordIntegration: boolean = $ref(false); async function init() { const meta = await os.api("admin/meta"); - enableTwitterIntegration = meta.enableTwitterIntegration; enableGithubIntegration = meta.enableGithubIntegration; enableDiscordIntegration = meta.enableDiscordIntegration; } diff --git a/packages/client/src/pages/settings/integration.vue b/packages/client/src/pages/settings/integration.vue index ef4182f39..933113a30 100644 --- a/packages/client/src/pages/settings/integration.vue +++ b/packages/client/src/pages/settings/integration.vue @@ -1,50 +1,29 @@