Merge branch 'develop' into swn
This commit is contained in:
commit
1662119933
32
.github/workflows/docker.yml
vendored
Normal file
32
.github/workflows/docker.yml
vendored
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
name: Publish Docker image
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [published]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
push_to_registry:
|
||||||
|
name: Push Docker image to Docker Hub
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Check out the repo
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Docker meta
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v3
|
||||||
|
with:
|
||||||
|
images: misskey/misskey
|
||||||
|
- name: Log in to Docker Hub
|
||||||
|
uses: docker/login-action@v1
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
|
- name: Build and Push to Docker Hub
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: true
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
|
@ -9,6 +9,13 @@
|
||||||
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
## 12.x.x (unreleased)
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
- リモートユーザーのDeleteアクティビティに対応
|
||||||
|
|
||||||
|
### Bugfixes
|
||||||
|
|
||||||
## 12.90.1 (2021/09/05)
|
## 12.90.1 (2021/09/05)
|
||||||
|
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
|
|
@ -1150,6 +1150,10 @@ _permissions:
|
||||||
"write:user-groups": "ユーザーグループを操作する"
|
"write:user-groups": "ユーザーグループを操作する"
|
||||||
"read:channels": "チャンネルを見る"
|
"read:channels": "チャンネルを見る"
|
||||||
"write:channels": "チャンネルを操作する"
|
"write:channels": "チャンネルを操作する"
|
||||||
|
"read:gallery": "ギャラリーを見る"
|
||||||
|
"write:gallery": "ギャラリーを操作する"
|
||||||
|
"read:gallery-likes": "ギャラリーのいいねを見る"
|
||||||
|
"write:gallery-likes": "ギャラリーのいいねを操作する"
|
||||||
|
|
||||||
_auth:
|
_auth:
|
||||||
shareAccess: "「{name}」がアカウントにアクセスすることを許可しますか?"
|
shareAccess: "「{name}」がアカウントにアクセスすることを許可しますか?"
|
||||||
|
|
|
@ -32,3 +32,4 @@ export const kinds = [
|
||||||
'read:gallery-likes',
|
'read:gallery-likes',
|
||||||
'write:gallery-likes',
|
'write:gallery-likes',
|
||||||
];
|
];
|
||||||
|
// IF YOU ADD KINDS(PERMISSIONS), YOU MUST ADD TRANSLATIONS (under _permissions).
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { Note } from '@/models/entities/note';
|
||||||
import { NoteReaction } from '@/models/entities/note-reaction';
|
import { NoteReaction } from '@/models/entities/note-reaction';
|
||||||
import { User } from '@/models/entities/user';
|
import { User } from '@/models/entities/user';
|
||||||
import { aggregateNoteEmojis, prefetchEmojis } from '@/misc/populate-emojis';
|
import { aggregateNoteEmojis, prefetchEmojis } from '@/misc/populate-emojis';
|
||||||
|
import { notificationTypes } from '@/types';
|
||||||
|
|
||||||
export type PackedNotification = SchemaType<typeof packedNotificationSchema>;
|
export type PackedNotification = SchemaType<typeof packedNotificationSchema>;
|
||||||
|
|
||||||
|
@ -124,20 +125,53 @@ export const packedNotificationSchema = {
|
||||||
optional: false as const, nullable: false as const,
|
optional: false as const, nullable: false as const,
|
||||||
format: 'date-time',
|
format: 'date-time',
|
||||||
},
|
},
|
||||||
|
isRead: {
|
||||||
|
type: 'boolean' as const,
|
||||||
|
optional: false as const, nullable: false as const,
|
||||||
|
},
|
||||||
type: {
|
type: {
|
||||||
type: 'string' as const,
|
type: 'string' as const,
|
||||||
optional: false as const, nullable: false as const,
|
optional: false as const, nullable: false as const,
|
||||||
enum: ['follow', 'followRequestAccepted', 'receiveFollowRequest', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote'],
|
enum: [...notificationTypes],
|
||||||
},
|
|
||||||
userId: {
|
|
||||||
type: 'string' as const,
|
|
||||||
optional: true as const, nullable: true as const,
|
|
||||||
format: 'id',
|
|
||||||
},
|
},
|
||||||
user: {
|
user: {
|
||||||
type: 'object' as const,
|
type: 'object' as const,
|
||||||
ref: 'User',
|
ref: 'User',
|
||||||
optional: true as const, nullable: true as const,
|
optional: true as const, nullable: true as const,
|
||||||
},
|
},
|
||||||
|
userId: {
|
||||||
|
type: 'string' as const,
|
||||||
|
optional: true as const, nullable: true as const,
|
||||||
|
format: 'id',
|
||||||
|
},
|
||||||
|
note: {
|
||||||
|
type: 'object' as const,
|
||||||
|
ref: 'Note',
|
||||||
|
optional: true as const, nullable: true as const,
|
||||||
|
},
|
||||||
|
reaction: {
|
||||||
|
type: 'string' as const,
|
||||||
|
optional: true as const, nullable: true as const,
|
||||||
|
},
|
||||||
|
choice: {
|
||||||
|
type: 'number' as const,
|
||||||
|
optional: true as const, nullable: true as const,
|
||||||
|
},
|
||||||
|
invitation: {
|
||||||
|
type: 'object' as const,
|
||||||
|
optional: true as const, nullable: true as const,
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
type: 'string' as const,
|
||||||
|
optional: true as const, nullable: true as const,
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
type: 'string' as const,
|
||||||
|
optional: true as const, nullable: true as const,
|
||||||
|
},
|
||||||
|
icon: {
|
||||||
|
type: 'string' as const,
|
||||||
|
optional: true as const, nullable: true as const,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
26
src/remote/activitypub/kernel/delete/actor.ts
Normal file
26
src/remote/activitypub/kernel/delete/actor.ts
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
import { apLogger } from '../../logger';
|
||||||
|
import { createDeleteAccountJob } from '@/queue';
|
||||||
|
import { IRemoteUser } from '@/models/entities/user';
|
||||||
|
import { Users } from '@/models/index';
|
||||||
|
|
||||||
|
const logger = apLogger;
|
||||||
|
|
||||||
|
export async function deleteActor(actor: IRemoteUser, uri: string): Promise<string> {
|
||||||
|
logger.info(`Deleting the Actor: ${uri}`);
|
||||||
|
|
||||||
|
if (actor.uri !== uri) {
|
||||||
|
return `skip: delete actor ${actor.uri} !== ${uri}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actor.isDeleted) {
|
||||||
|
logger.info(`skip: already deleted`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const job = await createDeleteAccountJob(actor);
|
||||||
|
|
||||||
|
await Users.update(actor.id, {
|
||||||
|
isDeleted: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
return `ok: queued ${job.name} ${job.id}`;
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ import deleteNote from './note';
|
||||||
import { IRemoteUser } from '@/models/entities/user';
|
import { IRemoteUser } from '@/models/entities/user';
|
||||||
import { IDelete, getApId, isTombstone, IObject, validPost, validActor } from '../../type';
|
import { IDelete, getApId, isTombstone, IObject, validPost, validActor } from '../../type';
|
||||||
import { toSingle } from '@/prelude/array';
|
import { toSingle } from '@/prelude/array';
|
||||||
|
import { deleteActor } from './actor';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 削除アクティビティを捌きます
|
* 削除アクティビティを捌きます
|
||||||
|
@ -41,7 +42,7 @@ export default async (actor: IRemoteUser, activity: IDelete): Promise<string> =>
|
||||||
if (validPost.includes(formarType)) {
|
if (validPost.includes(formarType)) {
|
||||||
return await deleteNote(actor, uri);
|
return await deleteNote(actor, uri);
|
||||||
} else if (validActor.includes(formarType)) {
|
} else if (validActor.includes(formarType)) {
|
||||||
return `Delete Actor is not implanted`;
|
return await deleteActor(actor, uri);
|
||||||
} else {
|
} else {
|
||||||
return `Unknown type ${formarType}`;
|
return `Unknown type ${formarType}`;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue