diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2020-02-01 07:16:52 +0900 |
|---|---|---|
| committer | syuilo <Syuilotan@yahoo.co.jp> | 2020-02-01 07:16:52 +0900 |
| commit | 7ed3448e13847f3ba807be1354e90c912fbefd9a (patch) | |
| tree | a9d91176e5a95f90e2af570ae900641f651e77aa /src | |
| parent | Update gulpfile.ts (diff) | |
| download | sharkey-7ed3448e13847f3ba807be1354e90c912fbefd9a.tar.gz sharkey-7ed3448e13847f3ba807be1354e90c912fbefd9a.tar.bz2 sharkey-7ed3448e13847f3ba807be1354e90c912fbefd9a.zip | |
Resolve #1669
Diffstat (limited to 'src')
| -rw-r--r-- | src/client/pages/settings/integration.vue | 27 | ||||
| -rw-r--r-- | src/models/entities/user-profile.ts | 83 | ||||
| -rw-r--r-- | src/models/repositories/user.ts | 14 | ||||
| -rw-r--r-- | src/remote/activitypub/models/person.ts | 9 | ||||
| -rw-r--r-- | src/remote/activitypub/renderer/person.ts | 39 | ||||
| -rw-r--r-- | src/server/api/endpoints/i/2fa/done.ts | 2 | ||||
| -rw-r--r-- | src/server/api/endpoints/i/2fa/register.ts | 2 | ||||
| -rw-r--r-- | src/server/api/endpoints/i/2fa/unregister.ts | 2 | ||||
| -rw-r--r-- | src/server/api/endpoints/i/change-password.ts | 2 | ||||
| -rw-r--r-- | src/server/api/endpoints/i/update-email.ts | 4 | ||||
| -rw-r--r-- | src/server/api/endpoints/i/update.ts | 2 | ||||
| -rw-r--r-- | src/server/api/endpoints/room/show.ts | 6 | ||||
| -rw-r--r-- | src/server/api/endpoints/room/update.ts | 2 | ||||
| -rw-r--r-- | src/server/api/service/discord.ts | 58 | ||||
| -rw-r--r-- | src/server/api/service/github.ts | 31 | ||||
| -rw-r--r-- | src/server/api/service/twitter.ts | 34 |
16 files changed, 102 insertions, 215 deletions
diff --git a/src/client/pages/settings/integration.vue b/src/client/pages/settings/integration.vue index bb0346d1c9..74efe3941c 100644 --- a/src/client/pages/settings/integration.vue +++ b/src/client/pages/settings/integration.vue @@ -1,24 +1,25 @@ <template> <section class="_card" v-if="enableTwitterIntegration || enableDiscordIntegration || enableGithubIntegration"> <div class="_title"><fa :icon="faShareAlt"/> {{ $t('integration') }}</div> + <div class="_content" v-if="enableTwitterIntegration"> <header><fa :icon="faTwitter"/> Twitter</header> - <p v-if="$store.state.i.twitter">{{ $t('connectedTo') }}: <a :href="`https://twitter.com/${$store.state.i.twitter.screenName}`" rel="nofollow noopener" target="_blank">@{{ $store.state.i.twitter.screenName }}</a></p> - <mk-button v-if="$store.state.i.twitter" @click="disconnectTwitter">{{ $t('disconnectSerice') }}</mk-button> + <p v-if="integrations.twitter">{{ $t('connectedTo') }}: <a :href="`https://twitter.com/${integrations.twitter.screenName}`" rel="nofollow noopener" target="_blank">@{{ integrations.twitter.screenName }}</a></p> + <mk-button v-if="integrations.twitter" @click="disconnectTwitter">{{ $t('disconnectSerice') }}</mk-button> <mk-button v-else @click="connectTwitter">{{ $t('connectSerice') }}</mk-button> </div> <div class="_content" v-if="enableDiscordIntegration"> <header><fa :icon="faDiscord"/> Discord</header> - <p v-if="$store.state.i.discord">{{ $t('connectedTo') }}: <a :href="`https://discordapp.com/users/${$store.state.i.discord.id}`" rel="nofollow noopener" target="_blank">@{{ $store.state.i.discord.username }}#{{ $store.state.i.discord.discriminator }}</a></p> - <mk-button v-if="$store.state.i.discord" @click="disconnectDiscord">{{ $t('disconnectSerice') }}</mk-button> + <p v-if="integrations.discord">{{ $t('connectedTo') }}: <a :href="`https://discordapp.com/users/${integrations.discord.id}`" rel="nofollow noopener" target="_blank">@{{ integrations.discord.username }}#{{ integrations.discord.discriminator }}</a></p> + <mk-button v-if="integrations.discord" @click="disconnectDiscord">{{ $t('disconnectSerice') }}</mk-button> <mk-button v-else @click="connectDiscord">{{ $t('connectSerice') }}</mk-button> </div> <div class="_content" v-if="enableGithubIntegration"> <header><fa :icon="faGithub"/> GitHub</header> - <p v-if="$store.state.i.github">{{ $t('connectedTo') }}: <a :href="`https://github.com/${$store.state.i.github.login}`" rel="nofollow noopener" target="_blank">@{{ $store.state.i.github.login }}</a></p> - <mk-button v-if="$store.state.i.github" @click="disconnectGithub">{{ $t('disconnectSerice') }}</mk-button> + <p v-if="integrations.github">{{ $t('connectedTo') }}: <a :href="`https://github.com/${integrations.github.login}`" rel="nofollow noopener" target="_blank">@{{ integrations.github.login }}</a></p> + <mk-button v-if="integrations.github" @click="disconnectGithub">{{ $t('disconnectSerice') }}</mk-button> <mk-button v-else @click="connectGithub">{{ $t('connectSerice') }}</mk-button> </div> </section> @@ -52,6 +53,12 @@ export default Vue.extend({ }; }, + computed: { + integrations() { + return this.$store.state.i.integrations; + } + }, + created() { this.$root.getMeta().then(meta => { this.enableTwitterIntegration = meta.enableTwitterIntegration; @@ -66,14 +73,14 @@ export default Vue.extend({ ` domain=${document.location.hostname}; max-age=31536000;` + (document.location.protocol.startsWith('https') ? ' secure' : ''); } - this.$watch('$store.state.i', () => { - if (this.$store.state.i.twitter) { + this.$watch('integrations', () => { + if (this.integrations.twitter) { if (this.twitterForm) this.twitterForm.close(); } - if (this.$store.state.i.discord) { + if (this.integrations.discord) { if (this.discordForm) this.discordForm.close(); } - if (this.$store.state.i.github) { + if (this.integrations.github) { if (this.githubForm) this.githubForm.close(); } }, { diff --git a/src/models/entities/user-profile.ts b/src/models/entities/user-profile.ts index 1244fa4390..278e8ce815 100644 --- a/src/models/entities/user-profile.ts +++ b/src/models/entities/user-profile.ts @@ -137,87 +137,10 @@ export class UserProfile { @JoinColumn() public pinnedPage: Page | null; - //#region Linking - @Column('boolean', { - default: false, - }) - public twitter: boolean; - - @Column('varchar', { - length: 64, nullable: true, default: null, - }) - public twitterAccessToken: string | null; - - @Column('varchar', { - length: 64, nullable: true, default: null, - }) - public twitterAccessTokenSecret: string | null; - - @Column('varchar', { - length: 64, nullable: true, default: null, - }) - public twitterUserId: string | null; - - @Column('varchar', { - length: 64, nullable: true, default: null, - }) - public twitterScreenName: string | null; - - @Column('boolean', { - default: false, - }) - public github: boolean; - - @Column('varchar', { - length: 64, nullable: true, default: null, - }) - public githubAccessToken: string | null; - - @Column('varchar', { - length: 64, nullable: true, default: null, - }) - public githubId: string | null; - - @Column('varchar', { - length: 64, nullable: true, default: null, - }) - public githubLogin: string | null; - - @Column('boolean', { - default: false, - }) - public discord: boolean; - - @Column('varchar', { - length: 64, nullable: true, default: null, - }) - public discordAccessToken: string | null; - - @Column('varchar', { - length: 64, nullable: true, default: null, - }) - public discordRefreshToken: string | null; - - @Column('varchar', { - length: 64, nullable: true, default: null, - }) - public discordExpiresDate: string | null; - - @Column('varchar', { - length: 64, nullable: true, default: null, - }) - public discordId: string | null; - - @Column('varchar', { - length: 64, nullable: true, default: null, - }) - public discordUsername: string | null; - - @Column('varchar', { - length: 64, nullable: true, default: null, + @Column('jsonb', { + default: {} }) - public discordDiscriminator: string | null; - //#endregion + public integrations: Record<string, any>; //#region Denormalized fields @Index() diff --git a/src/models/repositories/user.ts b/src/models/repositories/user.ts index 3b3ed6b793..25ce00cdc4 100644 --- a/src/models/repositories/user.ts +++ b/src/models/repositories/user.ts @@ -213,19 +213,6 @@ export class UserRepository extends Repository<User> { userId: user.id }).then(result => result >= 1) : false, - twitter: profile!.twitter ? { - id: profile!.twitterUserId, - screenName: profile!.twitterScreenName - } : null, - github: profile!.github ? { - id: profile!.githubId, - login: profile!.githubLogin - } : null, - discord: profile!.discord ? { - id: profile!.discordId, - username: profile!.discordUsername, - discriminator: profile!.discordDiscriminator - } : null, } : {}), ...(opts.detail && meId === user.id ? { @@ -242,6 +229,7 @@ export class UserRepository extends Repository<User> { pendingReceivedFollowRequestsCount: FollowRequests.count({ followeeId: user.id }), + integrations: profile?.integrations, } : {}), ...(opts.includeSecrets ? { diff --git a/src/remote/activitypub/models/person.ts b/src/remote/activitypub/models/person.ts index 6fad553c91..f9ffa4d77a 100644 --- a/src/remote/activitypub/models/person.ts +++ b/src/remote/activitypub/models/person.ts @@ -306,7 +306,7 @@ export async function updatePerson(uri: string, resolver?: Resolver | null, hint const emojiNames = emojis.map(emoji => emoji.name); - const { fields, services } = analyzeAttachments(person.attachment || []); + const { fields } = analyzeAttachments(person.attachment || []); const tags = extractHashtags(person.tag).map(tag => tag.toLowerCase()).splice(0, 32); @@ -347,13 +347,6 @@ export async function updatePerson(uri: string, resolver?: Resolver | null, hint url: person.url, fields, description: person.summary ? fromHtml(person.summary) : null, - twitterUserId: services.twitter ? services.twitter.userId : null, - twitterScreenName: services.twitter ? services.twitter.screenName : null, - githubId: services.github ? services.github.id : null, - githubLogin: services.github ? services.github.login : null, - discordId: services.discord ? services.discord.id : null, - discordUsername: services.discord ? services.discord.username : null, - discordDiscriminator: services.discord ? services.discord.discriminator : null, }); // ハッシュタグ更新 diff --git a/src/remote/activitypub/renderer/person.ts b/src/remote/activitypub/renderer/person.ts index 07a0eeed42..af0e446ac1 100644 --- a/src/remote/activitypub/renderer/person.ts +++ b/src/remote/activitypub/renderer/person.ts @@ -39,45 +39,6 @@ export async function renderPerson(user: ILocalUser) { } } - if (profile.twitter) { - attachment.push({ - type: 'PropertyValue', - name: 'Twitter', - value: `<a href="https://twitter.com/intent/user?user_id=${profile.twitterUserId}" rel="me nofollow noopener" target="_blank"><span>@${profile.twitterScreenName}</span></a>`, - identifier: { - type: 'PropertyValue', - name: 'misskey:authentication:twitter', - value: `${profile.twitterUserId}@${profile.twitterScreenName}` - } - }); - } - - if (profile.github) { - attachment.push({ - type: 'PropertyValue', - name: 'GitHub', - value: `<a href="https://github.com/${profile.githubLogin}" rel="me nofollow noopener" target="_blank"><span>@${profile.githubLogin}</span></a>`, - identifier: { - type: 'PropertyValue', - name: 'misskey:authentication:github', - value: `${profile.githubId}@${profile.githubLogin}` - } - }); - } - - if (profile.discord) { - attachment.push({ - type: 'PropertyValue', - name: 'Discord', - value: `<a href="https://discordapp.com/users/${profile.discordId}" rel="me nofollow noopener" target="_blank"><span>${profile.discordUsername}#${profile.discordDiscriminator}</span></a>`, - identifier: { - type: 'PropertyValue', - name: 'misskey:authentication:discord', - value: `${profile.discordId}@${profile.discordUsername}#${profile.discordDiscriminator}` - } - }); - } - const emojis = await getEmojis(user.emojis); const apemojis = emojis.map(emoji => renderEmoji(emoji)); diff --git a/src/server/api/endpoints/i/2fa/done.ts b/src/server/api/endpoints/i/2fa/done.ts index c134e1b226..3420bc3f64 100644 --- a/src/server/api/endpoints/i/2fa/done.ts +++ b/src/server/api/endpoints/i/2fa/done.ts @@ -35,7 +35,7 @@ export default define(meta, async (ps, user) => { throw new Error('not verified'); } - await UserProfiles.update({ userId: user.id }, { + await UserProfiles.update(user.id, { twoFactorSecret: profile.twoFactorTempSecret, twoFactorEnabled: true }); diff --git a/src/server/api/endpoints/i/2fa/register.ts b/src/server/api/endpoints/i/2fa/register.ts index bd46b7c68c..112cdd6b7c 100644 --- a/src/server/api/endpoints/i/2fa/register.ts +++ b/src/server/api/endpoints/i/2fa/register.ts @@ -34,7 +34,7 @@ export default define(meta, async (ps, user) => { length: 32 }); - await UserProfiles.update({ userId: user.id }, { + await UserProfiles.update(user.id, { twoFactorTempSecret: secret.base32 }); diff --git a/src/server/api/endpoints/i/2fa/unregister.ts b/src/server/api/endpoints/i/2fa/unregister.ts index 99483143cc..8fda128095 100644 --- a/src/server/api/endpoints/i/2fa/unregister.ts +++ b/src/server/api/endpoints/i/2fa/unregister.ts @@ -26,7 +26,7 @@ export default define(meta, async (ps, user) => { throw new Error('incorrect password'); } - await UserProfiles.update({ userId: user.id }, { + await UserProfiles.update(user.id, { twoFactorSecret: null, twoFactorEnabled: false }); diff --git a/src/server/api/endpoints/i/change-password.ts b/src/server/api/endpoints/i/change-password.ts index 07d2d864d2..0f44bbf826 100644 --- a/src/server/api/endpoints/i/change-password.ts +++ b/src/server/api/endpoints/i/change-password.ts @@ -34,7 +34,7 @@ export default define(meta, async (ps, user) => { const salt = await bcrypt.genSalt(8); const hash = await bcrypt.hash(ps.newPassword, salt); - await UserProfiles.update({ userId: user.id }, { + await UserProfiles.update(user.id, { password: hash }); }); diff --git a/src/server/api/endpoints/i/update-email.ts b/src/server/api/endpoints/i/update-email.ts index ca95e612a3..92ac3d79eb 100644 --- a/src/server/api/endpoints/i/update-email.ts +++ b/src/server/api/endpoints/i/update-email.ts @@ -49,7 +49,7 @@ export default define(meta, async (ps, user) => { throw new ApiError(meta.errors.incorrectPassword); } - await UserProfiles.update({ userId: user.id }, { + await UserProfiles.update(user.id, { email: ps.email, emailVerified: false, emailVerifyCode: null @@ -66,7 +66,7 @@ export default define(meta, async (ps, user) => { if (ps.email != null) { const code = rndstr('a-z0-9', 16); - await UserProfiles.update({ userId: user.id }, { + await UserProfiles.update(user.id, { emailVerifyCode: code }); diff --git a/src/server/api/endpoints/i/update.ts b/src/server/api/endpoints/i/update.ts index f7f03e84a3..14ed27fe5a 100644 --- a/src/server/api/endpoints/i/update.ts +++ b/src/server/api/endpoints/i/update.ts @@ -268,7 +268,7 @@ export default define(meta, async (ps, user, app) => { //#endregion if (Object.keys(updates).length > 0) await Users.update(user.id, updates); - if (Object.keys(profileUpdates).length > 0) await UserProfiles.update({ userId: user.id }, profileUpdates); + if (Object.keys(profileUpdates).length > 0) await UserProfiles.update(user.id, profileUpdates); const iObj = await Users.pack(user.id, user, { detail: true, diff --git a/src/server/api/endpoints/room/show.ts b/src/server/api/endpoints/room/show.ts index 17634834ac..2dc69210a0 100644 --- a/src/server/api/endpoints/room/show.ts +++ b/src/server/api/endpoints/room/show.ts @@ -54,7 +54,7 @@ export default define(meta, async (ps, me) => { const profile = await UserProfiles.findOne(user.id).then(ensure); if (profile.room.furnitures == null) { - await UserProfiles.update({ userId: user.id }, { + await UserProfiles.update(user.id, { room: { furnitures: [], ...profile.room @@ -66,7 +66,7 @@ export default define(meta, async (ps, me) => { if (profile.room.roomType == null) { const initialType = 'default'; - await UserProfiles.update({ userId: user.id }, { + await UserProfiles.update(user.id, { room: { roomType: initialType as any, ...profile.room @@ -78,7 +78,7 @@ export default define(meta, async (ps, me) => { if (profile.room.carpetColor == null) { const initialColor = '#85CAF0'; - await UserProfiles.update({ userId: user.id }, { + await UserProfiles.update(user.id, { room: { carpetColor: initialColor as any, ...profile.room diff --git a/src/server/api/endpoints/room/update.ts b/src/server/api/endpoints/room/update.ts index 897f65f2d2..97586eb6f3 100644 --- a/src/server/api/endpoints/room/update.ts +++ b/src/server/api/endpoints/room/update.ts @@ -32,7 +32,7 @@ export const meta = { }; export default define(meta, async (ps, user) => { - await UserProfiles.update({ userId: user.id }, { + await UserProfiles.update(user.id, { room: ps.room as any }); diff --git a/src/server/api/service/discord.ts b/src/server/api/service/discord.ts index d5ca05577c..f9f3026aa8 100644 --- a/src/server/api/service/discord.ts +++ b/src/server/api/service/discord.ts @@ -46,16 +46,12 @@ router.get('/disconnect/discord', async ctx => { token: userToken }).then(ensure); - await UserProfiles.update({ - userId: user.id - }, { - discord: false, - discordAccessToken: null, - discordRefreshToken: null, - discordExpiresDate: null, - discordId: null, - discordUsername: null, - discordDiscriminator: null, + const profile = await UserProfiles.findOne(user.id).then(ensure); + + delete profile.integrations.discord; + + await UserProfiles.update(user.id, { + integrations: profile.integrations, }); ctx.body = `Discordの連携を解除しました :v:`; @@ -203,7 +199,7 @@ router.get('/dc/cb', async ctx => { } const profile = await UserProfiles.createQueryBuilder() - .where('"discordId" = :id', { id: id }) + .where('"integrations"->"discord"->"id" = :id', { id: id }) .andWhere('"userHost" IS NULL') .getOne(); @@ -212,13 +208,17 @@ router.get('/dc/cb', async ctx => { return; } - await UserProfiles.update({ userId: profile.userId }, { - discord: true, - discordAccessToken: accessToken, - discordRefreshToken: refreshToken, - discordExpiresDate: expiresDate, - discordUsername: username, - discordDiscriminator: discriminator + await UserProfiles.update(profile.userId, { + integrations: { + ...profile.integrations, + discord: { + accessToken: accessToken, + refreshToken: refreshToken, + expiresDate: expiresDate, + username: username, + discriminator: discriminator + } + }, }); signin(ctx, await Users.findOne(profile.userId) as ILocalUser, true); @@ -284,14 +284,20 @@ router.get('/dc/cb', async ctx => { token: userToken }).then(ensure); - await UserProfiles.update({ userId: user.id }, { - discord: true, - discordAccessToken: accessToken, - discordRefreshToken: refreshToken, - discordExpiresDate: expiresDate, - discordId: id, - discordUsername: username, - discordDiscriminator: discriminator + const profile = await UserProfiles.findOne(user.id).then(ensure); + + await UserProfiles.update(user.id, { + integrations: { + ...profile.integrations, + discord: { + accessToken: accessToken, + refreshToken: refreshToken, + expiresDate: expiresDate, + id: id, + username: username, + discriminator: discriminator + } + } }); ctx.body = `Discord: @${username}#${discriminator} を、Misskey: @${user.username} に接続しました!`; diff --git a/src/server/api/service/github.ts b/src/server/api/service/github.ts index 071b4a96d1..ec9cce7ad8 100644 --- a/src/server/api/service/github.ts +++ b/src/server/api/service/github.ts @@ -46,13 +46,12 @@ router.get('/disconnect/github', async ctx => { token: userToken }).then(ensure); - await UserProfiles.update({ - userId: user.id - }, { - github: false, - githubAccessToken: null, - githubId: null, - githubLogin: null, + const profile = await UserProfiles.findOne(user.id).then(ensure); + + delete profile.integrations.github; + + await UserProfiles.update(user.id, { + integrations: profile.integrations, }); ctx.body = `GitHubの連携を解除しました :v:`; @@ -193,7 +192,7 @@ router.get('/gh/cb', async ctx => { } const link = await UserProfiles.createQueryBuilder() - .where('"githubId" = :id', { id: id }) + .where('"integrations"->"github"->"id" = :id', { id: id }) .andWhere('"userHost" IS NULL') .getOne(); @@ -260,11 +259,17 @@ router.get('/gh/cb', async ctx => { token: userToken }).then(ensure); - await UserProfiles.update({ userId: user.id }, { - github: true, - githubAccessToken: accessToken, - githubId: id, - githubLogin: login, + const profile = await UserProfiles.findOne(user.id).then(ensure); + + await UserProfiles.update(user.id, { + integrations: { + ...profile.integrations, + github: { + accessToken: accessToken, + id: id, + login: login, + } + } }); ctx.body = `GitHub: @${login} を、Misskey: @${user.username} に接続しました!`; diff --git a/src/server/api/service/twitter.ts b/src/server/api/service/twitter.ts index dc6c593201..881915b58f 100644 --- a/src/server/api/service/twitter.ts +++ b/src/server/api/service/twitter.ts @@ -45,14 +45,12 @@ router.get('/disconnect/twitter', async ctx => { token: userToken }).then(ensure); - await UserProfiles.update({ - userId: user.id - }, { - twitter: false, - twitterAccessToken: null, - twitterAccessTokenSecret: null, - twitterUserId: null, - twitterScreenName: null, + const profile = await UserProfiles.findOne(user.id).then(ensure); + + delete profile.integrations.twitter; + + await UserProfiles.update(user.id, { + integrations: profile.integrations, }); ctx.body = `Twitterの連携を解除しました :v:`; @@ -141,7 +139,7 @@ router.get('/tw/cb', async ctx => { const result = await twAuth!.done(JSON.parse(twCtx), ctx.query.oauth_verifier); const link = await UserProfiles.createQueryBuilder() - .where('"twitterUserId" = :id', { id: result.userId }) + .where('"integrations"->"twitter"->"userId" = :id', { id: result.userId }) .andWhere('"userHost" IS NULL') .getOne(); @@ -174,12 +172,18 @@ router.get('/tw/cb', async ctx => { token: userToken }).then(ensure); - await UserProfiles.update({ userId: user.id }, { - twitter: true, - twitterAccessToken: result.accessToken, - twitterAccessTokenSecret: result.accessTokenSecret, - twitterUserId: result.userId, - twitterScreenName: result.screenName, + const profile = await UserProfiles.findOne(user.id).then(ensure); + + 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} に接続しました!`; |