Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Undo Accept #7980

Merged
merged 3 commits into from
Dec 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions locales/ja-JP.yml
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,7 @@ pubSub: "Pub/Subのアカウント"
lastCommunication: "直近の通信"
resolved: "解決済み"
unresolved: "未解決"
breakFollow: "フォロワーを解除"
itsOn: "オンになっています"
itsOff: "オフになっています"
emailRequiredForSignup: "アカウント登録にメールアドレスを必須にする"
Expand Down
27 changes: 27 additions & 0 deletions packages/backend/src/remote/activitypub/kernel/undo/accept.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import unfollow from '@/services/following/delete';
import cancelRequest from '@/services/following/requests/cancel';
import {IAccept} from '../../type';
import { IRemoteUser } from '@/models/entities/user';
import { Followings } from '@/models/index';
import DbResolver from '../../db-resolver';

export default async (actor: IRemoteUser, activity: IAccept): Promise<string> => {
const dbResolver = new DbResolver();

const follower = await dbResolver.getUserFromApId(activity.object);
if (follower == null) {
return `skip: follower not found`;
}

const following = await Followings.findOne({
followerId: follower.id,
followeeId: actor.id
});

if (following) {
await unfollow(follower, actor);
return `ok: unfollowed`;
}

return `skip: フォローされていない`;
};
4 changes: 3 additions & 1 deletion packages/backend/src/remote/activitypub/kernel/undo/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { IRemoteUser } from '@/models/entities/user';
import { IUndo, isFollow, isBlock, isLike, isAnnounce, getApType } from '../../type';
import {IUndo, isFollow, isBlock, isLike, isAnnounce, getApType, isAccept} from '../../type';
import unfollow from './follow';
import unblock from './block';
import undoLike from './like';
import undoAccept from './accept';
import { undoAnnounce } from './announce';
import Resolver from '../../resolver';
import { apLogger } from '../../logger';
Expand All @@ -29,6 +30,7 @@ export default async (actor: IRemoteUser, activity: IUndo): Promise<string> => {
if (isBlock(object)) return await unblock(actor, object);
if (isLike(object)) return await undoLike(actor, object);
if (isAnnounce(object)) return await undoAnnounce(actor, object);
if (isAccept(object)) return await undoAccept(actor, object);

return `skip: unknown object type ${getApType(object)}`;
};
82 changes: 82 additions & 0 deletions packages/backend/src/server/api/endpoints/following/invalidate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import $ from 'cafy';
import { ID } from '@/misc/cafy-id';
import * as ms from 'ms';
import deleteFollowing from '@/services/following/delete';
import define from '../../define';
import { ApiError } from '../../error';
import { getUser } from '../../common/getters';
import { Followings, Users } from '@/models/index';

export const meta = {
tags: ['following', 'users'],

limit: {
duration: ms('1hour'),
max: 100
},

requireCredential: true as const,

kind: 'write:following',

params: {
userId: {
validator: $.type(ID),
}
},

errors: {
noSuchUser: {
message: 'No such user.',
code: 'NO_SUCH_USER',
id: '5b12c78d-2b28-4dca-99d2-f56139b42ff8'
},

followerIsYourself: {
message: 'Follower is yourself.',
code: 'FOLLOWER_IS_YOURSELF',
id: '07dc03b9-03da-422d-885b-438313707662'
},

notFollowing: {
message: 'The other use is not following you.',
code: 'NOT_FOLLOWING',
id: '5dbf82f5-c92b-40b1-87d1-6c8c0741fd09'
},
},

res: {
type: 'object' as const,
optional: false as const, nullable: false as const,
ref: 'User'
}
};

export default define(meta, async (ps, user) => {
const followee = user;

// Check if the follower is yourself
if (user.id === ps.userId) {
throw new ApiError(meta.errors.followerIsYourself);
}

// Get follower
const follower = await getUser(ps.userId).catch(e => {
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser);
throw e;
});

// Check not following
const exist = await Followings.findOne({
followerId: follower.id,
followeeId: followee.id
});

if (exist == null) {
throw new ApiError(meta.errors.notFollowing);
}

await deleteFollowing(follower, followee);

return await Users.pack(followee.id, user);
});
7 changes: 7 additions & 0 deletions packages/backend/src/services/following/delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { publishMainStream, publishUserEvent } from '@/services/stream';
import { renderActivity } from '@/remote/activitypub/renderer/index';
import renderFollow from '@/remote/activitypub/renderer/follow';
import renderUndo from '@/remote/activitypub/renderer/undo';
import renderReject from '@/remote/activitypub/renderer/reject';
import { deliver } from '@/queue/index';
import Logger from '../logger';
import { registerOrFetchInstanceDoc } from '../register-or-fetch-instance-doc';
Expand Down Expand Up @@ -40,6 +41,12 @@ export default async function(follower: { id: User['id']; host: User['host']; ur
const content = renderActivity(renderUndo(renderFollow(follower, followee), follower));
deliver(follower, content, followee.inbox);
}

if (Users.isLocalUser(followee) && Users.isRemoteUser(follower)) {
// local user has null host
const content = renderActivity(renderReject(renderFollow(follower, followee), followee));
deliver(followee, content, follower.inbox);
}
}

export async function decrementFollowing(follower: { id: User['id']; host: User['host']; }, followee: { id: User['id']; host: User['host']; }) {
Expand Down
16 changes: 16 additions & 0 deletions packages/client/src/scripts/get-user-menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,14 @@ export function getUserMenu(user) {
return !confirm.canceled;
}

async function invalidateFollow() {
os.apiWithDialog('following/invalidate', {
userId: user.id
}).then(() => {
user.isFollowed = !user.isFollowed;
})
}

let menu = [{
icon: 'fas fa-at',
text: i18n.locale.copyUsername,
Expand Down Expand Up @@ -153,6 +161,14 @@ export function getUserMenu(user) {
action: toggleBlock
}]);

if (user.isFollowed) {
menu = menu.concat([{
icon: 'fas fa-unlink',
text: i18n.locale.breakFollow,
action: invalidateFollow
}]);
}

menu = menu.concat([null, {
icon: 'fas fa-exclamation-circle',
text: i18n.locale.reportAbuse,
Expand Down