秘密鍵の変更は、フラグではなく鍵を引き回すようにする
This commit is contained in:
parent
6e4357c378
commit
430f0b7911
9 changed files with 82 additions and 53 deletions
|
@ -13,6 +13,7 @@ import { RelayService } from '@/core/RelayService.js';
|
||||||
import { ApDeliverManagerService } from '@/core/activitypub/ApDeliverManagerService.js';
|
import { ApDeliverManagerService } from '@/core/activitypub/ApDeliverManagerService.js';
|
||||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
|
import type { PrivateKey } from './activitypub/type.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AccountUpdateService implements OnModuleInit {
|
export class AccountUpdateService implements OnModuleInit {
|
||||||
|
@ -39,7 +40,7 @@ export class AccountUpdateService implements OnModuleInit {
|
||||||
* @param userId ユーザーID
|
* @param userId ユーザーID
|
||||||
* @param isKeyUpdation Ed25519キーの作成など公開鍵のアップデートによる呼び出しか? trueにするとメインキーを使うようになる
|
* @param isKeyUpdation Ed25519キーの作成など公開鍵のアップデートによる呼び出しか? trueにするとメインキーを使うようになる
|
||||||
*/
|
*/
|
||||||
public async publishToFollowers(userId: MiUser['id'], isKeyUpdation: boolean = false) {
|
public async publishToFollowers(userId: MiUser['id'], deliverKey?: PrivateKey) {
|
||||||
const user = await this.usersRepository.findOneBy({ id: userId });
|
const user = await this.usersRepository.findOneBy({ id: userId });
|
||||||
if (user == null) throw new Error('user not found');
|
if (user == null) throw new Error('user not found');
|
||||||
|
|
||||||
|
@ -47,8 +48,8 @@ export class AccountUpdateService implements OnModuleInit {
|
||||||
if (this.userEntityService.isLocalUser(user)) {
|
if (this.userEntityService.isLocalUser(user)) {
|
||||||
const content = this.apRendererService.addContext(this.apRendererService.renderUpdate(await this.apRendererService.renderPerson(user), user));
|
const content = this.apRendererService.addContext(this.apRendererService.renderUpdate(await this.apRendererService.renderPerson(user), user));
|
||||||
await Promise.allSettled([
|
await Promise.allSettled([
|
||||||
this.apDeliverManagerService.deliverToFollowers(user, content, isKeyUpdation),
|
this.apDeliverManagerService.deliverToFollowers(user, content, deliverKey),
|
||||||
this.relayService.deliverToRelays(user, content, isKeyUpdation),
|
this.relayService.deliverToRelays(user, content, deliverKey),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
import { randomUUID } from 'node:crypto';
|
import { randomUUID } from 'node:crypto';
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import type { IActivity } from '@/core/activitypub/type.js';
|
import type { IActivity, PrivateKey } from '@/core/activitypub/type.js';
|
||||||
import type { MiDriveFile } from '@/models/DriveFile.js';
|
import type { MiDriveFile } from '@/models/DriveFile.js';
|
||||||
import type { MiWebhook, webhookEventTypes } from '@/models/Webhook.js';
|
import type { MiWebhook, webhookEventTypes } from '@/models/Webhook.js';
|
||||||
import type { Config } from '@/config.js';
|
import type { Config } from '@/config.js';
|
||||||
|
@ -70,7 +70,7 @@ export class QueueService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async deliver(user: ThinUser, content: IActivity | null, to: string | null, isSharedInbox: boolean, forceMainKey?: boolean) {
|
public async deliver(user: ThinUser, content: IActivity | null, to: string | null, isSharedInbox: boolean, privateKey?: PrivateKey) {
|
||||||
if (content == null) return null;
|
if (content == null) return null;
|
||||||
if (to == null) return null;
|
if (to == null) return null;
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ export class QueueService {
|
||||||
digest: await genRFC3230DigestHeader(contentBody, 'SHA-256'),
|
digest: await genRFC3230DigestHeader(contentBody, 'SHA-256'),
|
||||||
to,
|
to,
|
||||||
isSharedInbox,
|
isSharedInbox,
|
||||||
forceMainKey,
|
privateKey,
|
||||||
};
|
};
|
||||||
|
|
||||||
return this.deliverQueue.add(to, data, {
|
return this.deliverQueue.add(to, data, {
|
||||||
|
@ -106,7 +106,7 @@ export class QueueService {
|
||||||
* @returns void
|
* @returns void
|
||||||
*/
|
*/
|
||||||
@bindThis
|
@bindThis
|
||||||
public async deliverMany(user: ThinUser, content: IActivity | null, inboxes: Map<string, boolean>, forceMainKey?: boolean) {
|
public async deliverMany(user: ThinUser, content: IActivity | null, inboxes: Map<string, boolean>, privateKey?: PrivateKey) {
|
||||||
if (content == null) return null;
|
if (content == null) return null;
|
||||||
const contentBody = JSON.stringify(content);
|
const contentBody = JSON.stringify(content);
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ export class QueueService {
|
||||||
content: contentBody,
|
content: contentBody,
|
||||||
to: d[0],
|
to: d[0],
|
||||||
isSharedInbox: d[1],
|
isSharedInbox: d[1],
|
||||||
forceMainKey,
|
privateKey,
|
||||||
} as DeliverJobData,
|
} as DeliverJobData,
|
||||||
opts,
|
opts,
|
||||||
})));
|
})));
|
||||||
|
|
|
@ -16,6 +16,7 @@ import { ApRendererService } from '@/core/activitypub/ApRendererService.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import { deepClone } from '@/misc/clone.js';
|
import { deepClone } from '@/misc/clone.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
|
import { PrivateKey } from './activitypub/type.js';
|
||||||
|
|
||||||
const ACTOR_USERNAME = 'relay.actor' as const;
|
const ACTOR_USERNAME = 'relay.actor' as const;
|
||||||
|
|
||||||
|
@ -111,7 +112,7 @@ export class RelayService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async deliverToRelays(user: { id: MiUser['id']; host: null; }, activity: any, forceMainKey?: boolean): Promise<void> {
|
public async deliverToRelays(user: { id: MiUser['id']; host: null; }, activity: any, privateKey?: PrivateKey): Promise<void> {
|
||||||
if (activity == null) return;
|
if (activity == null) return;
|
||||||
|
|
||||||
const relays = await this.relaysCache.fetch(() => this.relaysRepository.findBy({
|
const relays = await this.relaysCache.fetch(() => this.relaysRepository.findBy({
|
||||||
|
@ -125,7 +126,7 @@ export class RelayService {
|
||||||
const signed = await this.apRendererService.attachLdSignature(copy, user);
|
const signed = await this.apRendererService.attachLdSignature(copy, user);
|
||||||
|
|
||||||
for (const relay of relays) {
|
for (const relay of relays) {
|
||||||
this.queueService.deliver(user, signed, relay.inbox, false, forceMainKey);
|
this.queueService.deliver(user, signed, relay.inbox, false, privateKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import type { MiUserKeypair } from '@/models/UserKeypair.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { GlobalEventService, GlobalEvents } from '@/core/GlobalEventService.js';
|
import { GlobalEventService, GlobalEvents } from '@/core/GlobalEventService.js';
|
||||||
|
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UserKeypairService implements OnApplicationShutdown {
|
export class UserKeypairService implements OnApplicationShutdown {
|
||||||
|
@ -27,6 +28,7 @@ export class UserKeypairService implements OnApplicationShutdown {
|
||||||
private userKeypairsRepository: UserKeypairsRepository,
|
private userKeypairsRepository: UserKeypairsRepository,
|
||||||
|
|
||||||
private globalEventService: GlobalEventService,
|
private globalEventService: GlobalEventService,
|
||||||
|
private userEntityService: UserEntityService,
|
||||||
) {
|
) {
|
||||||
this.cache = new RedisKVCache<MiUserKeypair>(this.redisClient, 'userKeypair', {
|
this.cache = new RedisKVCache<MiUserKeypair>(this.redisClient, 'userKeypair', {
|
||||||
lifetime: 1000 * 60 * 60 * 24, // 24h
|
lifetime: 1000 * 60 * 60 * 24, // 24h
|
||||||
|
@ -44,6 +46,35 @@ export class UserKeypairService implements OnApplicationShutdown {
|
||||||
return await this.cache.fetch(userId);
|
return await this.cache.fetch(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param userIdOrHint user id or MiUserKeypair
|
||||||
|
* @param preferType 'main' or 'ed25519'; If 'ed25519' is specified and ed25519 keypair is not exists, it will return main keypair
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
@bindThis
|
||||||
|
public async getLocalUserKeypairWithKeyId(
|
||||||
|
userIdOrHint: MiUser['id'] | MiUserKeypair, preferType: 'main' | 'ed25519'
|
||||||
|
): Promise<{ keyId: string; publicKey: string; privateKey: string; }> {
|
||||||
|
const keypair = typeof userIdOrHint === 'string' ? await this.getUserKeypair(userIdOrHint) : userIdOrHint;
|
||||||
|
if (preferType === 'ed25519' && keypair.ed25519PublicKey != null && keypair.ed25519PrivateKey != null) {
|
||||||
|
return {
|
||||||
|
keyId: `${this.userEntityService.genLocalUserUri(keypair.userId)}#ed25519-key`,
|
||||||
|
publicKey: keypair.ed25519PublicKey,
|
||||||
|
privateKey: keypair.ed25519PrivateKey,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (preferType === 'main') {
|
||||||
|
return {
|
||||||
|
keyId: `${this.userEntityService.genLocalUserUri(keypair.userId)}#main-key`,
|
||||||
|
publicKey: keypair.publicKey,
|
||||||
|
privateKey: keypair.privateKey,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error('invalid type');
|
||||||
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async refresh(userId: MiUser['id']): Promise<void> {
|
public async refresh(userId: MiUser['id']): Promise<void> {
|
||||||
return await this.cache.refresh(userId);
|
return await this.cache.refresh(userId);
|
||||||
|
@ -52,14 +83,14 @@ export class UserKeypairService implements OnApplicationShutdown {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param userId user id
|
* @param userId user id
|
||||||
* @returns Promise<boolean> true if keypair is created, false if keypair is already exists
|
* @returns MiUserKeypair if keypair is created, void if keypair is already exists
|
||||||
*/
|
*/
|
||||||
@bindThis
|
@bindThis
|
||||||
public async refreshAndprepareEd25519KeyPair(userId: MiUser['id']): Promise<boolean> {
|
public async refreshAndprepareEd25519KeyPair(userId: MiUser['id']): Promise<MiUserKeypair | void> {
|
||||||
await this.refresh(userId);
|
await this.refresh(userId);
|
||||||
const keypair = await this.cache.fetch(userId);
|
const keypair = await this.cache.fetch(userId);
|
||||||
if (keypair.ed25519PublicKey != null) {
|
if (keypair.ed25519PublicKey != null) {
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ed25519 = await genEd25519KeyPair();
|
const ed25519 = await genEd25519KeyPair();
|
||||||
|
@ -68,7 +99,11 @@ export class UserKeypairService implements OnApplicationShutdown {
|
||||||
ed25519PrivateKey: ed25519.privateKey,
|
ed25519PrivateKey: ed25519.privateKey,
|
||||||
});
|
});
|
||||||
this.globalEventService.publishInternalEvent('userKeypairUpdated', { userId });
|
this.globalEventService.publishInternalEvent('userKeypairUpdated', { userId });
|
||||||
return true;
|
return {
|
||||||
|
...keypair,
|
||||||
|
ed25519PublicKey: ed25519.publicKey,
|
||||||
|
ed25519PrivateKey: ed25519.privateKey,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
|
|
|
@ -10,7 +10,7 @@ import type { FollowingsRepository } from '@/models/_.js';
|
||||||
import type { MiLocalUser, MiRemoteUser, MiUser } from '@/models/User.js';
|
import type { MiLocalUser, MiRemoteUser, MiUser } from '@/models/User.js';
|
||||||
import { QueueService } from '@/core/QueueService.js';
|
import { QueueService } from '@/core/QueueService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import type { IActivity } from '@/core/activitypub/type.js';
|
import type { IActivity, PrivateKey } from '@/core/activitypub/type.js';
|
||||||
import { ThinUser } from '@/queue/types.js';
|
import { ThinUser } from '@/queue/types.js';
|
||||||
import { AccountUpdateService } from '@/core/AccountUpdateService.js';
|
import { AccountUpdateService } from '@/core/AccountUpdateService.js';
|
||||||
import type Logger from '@/logger.js';
|
import type Logger from '@/logger.js';
|
||||||
|
@ -109,17 +109,19 @@ class DeliverManager {
|
||||||
* Execute delivers
|
* Execute delivers
|
||||||
*/
|
*/
|
||||||
@bindThis
|
@bindThis
|
||||||
public async execute(opts?: { forceMainKey?: boolean }): Promise<void> {
|
public async execute(opts?: { privateKey?: PrivateKey }): Promise<void> {
|
||||||
//#region MIGRATION
|
//#region MIGRATION
|
||||||
if (opts?.forceMainKey !== true) {
|
if (!opts?.privateKey) {
|
||||||
/**
|
/**
|
||||||
* ed25519の署名がなければ追加する
|
* ed25519の署名がなければ追加する
|
||||||
*/
|
*/
|
||||||
const created = await this.userKeypairService.refreshAndprepareEd25519KeyPair(this.actor.id);
|
const created = await this.userKeypairService.refreshAndprepareEd25519KeyPair(this.actor.id);
|
||||||
if (created) {
|
if (created) {
|
||||||
|
// createdが存在するということは新規作成されたということなので、フォロワーに配信する
|
||||||
this.logger.info(`ed25519 key pair created for user ${this.actor.id} and publishing to followers`);
|
this.logger.info(`ed25519 key pair created for user ${this.actor.id} and publishing to followers`);
|
||||||
// リモートに配信
|
// リモートに配信
|
||||||
await this.accountUpdateService.publishToFollowers(this.actor.id, true);
|
const keyPair = await this.userKeypairService.getLocalUserKeypairWithKeyId(created, 'ed25519');
|
||||||
|
await this.accountUpdateService.publishToFollowers(this.actor.id, { keyId: keyPair.keyId, privateKeyPem: keyPair.privateKey });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
|
@ -163,7 +165,7 @@ class DeliverManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
// deliver
|
// deliver
|
||||||
await this.queueService.deliverMany(this.actor, this.activity, inboxes);
|
await this.queueService.deliverMany(this.actor, this.activity, inboxes, opts?.privateKey);
|
||||||
this.logger.info(`Deliver queues dispatched: inboxes=${inboxes.size} actorId=${this.actor.id} activityId=${this.activity?.id}`);
|
this.logger.info(`Deliver queues dispatched: inboxes=${inboxes.size} actorId=${this.actor.id} activityId=${this.activity?.id}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -191,7 +193,7 @@ export class ApDeliverManagerService {
|
||||||
* @param forceMainKey Force to use main (rsa) key
|
* @param forceMainKey Force to use main (rsa) key
|
||||||
*/
|
*/
|
||||||
@bindThis
|
@bindThis
|
||||||
public async deliverToFollowers(actor: { id: MiLocalUser['id']; host: null; }, activity: IActivity, forceMainKey?: boolean): Promise<void> {
|
public async deliverToFollowers(actor: { id: MiLocalUser['id']; host: null; }, activity: IActivity, privateKey?: PrivateKey): Promise<void> {
|
||||||
const manager = new DeliverManager(
|
const manager = new DeliverManager(
|
||||||
this.userKeypairService,
|
this.userKeypairService,
|
||||||
this.followingsRepository,
|
this.followingsRepository,
|
||||||
|
@ -202,7 +204,7 @@ export class ApDeliverManagerService {
|
||||||
activity,
|
activity,
|
||||||
);
|
);
|
||||||
manager.addFollowersRecipe();
|
manager.addFollowersRecipe();
|
||||||
await manager.execute({ forceMainKey });
|
await manager.execute({ privateKey });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -15,18 +15,7 @@ import { LoggerService } from '@/core/LoggerService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import type Logger from '@/logger.js';
|
import type Logger from '@/logger.js';
|
||||||
import { validateContentTypeSetAsActivityPub } from '@/core/activitypub/misc/validator.js';
|
import { validateContentTypeSetAsActivityPub } from '@/core/activitypub/misc/validator.js';
|
||||||
|
import type { PrivateKey } from './type.js';
|
||||||
type Signed = {
|
|
||||||
request: Request;
|
|
||||||
signingString: string;
|
|
||||||
signature: string;
|
|
||||||
signatureHeader: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
type PrivateKey = {
|
|
||||||
privateKeyPem: string;
|
|
||||||
keyId: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export async function createSignedPost(args: { level: string; key: PrivateKey; url: string; body: string; digest?: string, additionalHeaders: Record<string, string> }) {
|
export async function createSignedPost(args: { level: string; key: PrivateKey; url: string; body: string; digest?: string, additionalHeaders: Record<string, string> }) {
|
||||||
const u = new URL(args.url);
|
const u = new URL(args.url);
|
||||||
|
@ -98,21 +87,19 @@ export class ApRequestService {
|
||||||
*/
|
*/
|
||||||
@bindThis
|
@bindThis
|
||||||
private async getPrivateKey(userId: MiUser['id'], level: string): Promise<PrivateKey> {
|
private async getPrivateKey(userId: MiUser['id'], level: string): Promise<PrivateKey> {
|
||||||
const keypair = await this.userKeypairService.getUserKeypair(userId);
|
const type = level === '00' || level === '10' ? 'ed25519' : 'main';
|
||||||
|
const keypair = await this.userKeypairService.getLocalUserKeypairWithKeyId(userId, type);
|
||||||
|
|
||||||
return (level !== '00' && level !== '10' && keypair.ed25519PrivateKey) ? {
|
return {
|
||||||
privateKeyPem: keypair.ed25519PrivateKey,
|
keyId: keypair.keyId,
|
||||||
keyId: `${this.config.url}/users/${userId}#ed25519-key`,
|
|
||||||
} : {
|
|
||||||
privateKeyPem: keypair.privateKey,
|
privateKeyPem: keypair.privateKey,
|
||||||
keyId: `${this.config.url}/users/${userId}#main-key`,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async signedPost(user: { id: MiUser['id'] }, url: string, object: unknown, level: string, digest?: string): Promise<void> {
|
public async signedPost(user: { id: MiUser['id'] }, url: string, object: unknown, level: string, digest?: string, key?: PrivateKey): Promise<void> {
|
||||||
const body = typeof object === 'string' ? object : JSON.stringify(object);
|
const body = typeof object === 'string' ? object : JSON.stringify(object);
|
||||||
const key = await this.getPrivateKey(user.id, level);
|
key = key ?? await this.getPrivateKey(user.id, level);
|
||||||
const req = await createSignedPost({
|
const req = await createSignedPost({
|
||||||
level,
|
level,
|
||||||
key,
|
key,
|
||||||
|
|
|
@ -326,3 +326,8 @@ export const isAnnounce = (object: IObject): object is IAnnounce => getApType(ob
|
||||||
export const isBlock = (object: IObject): object is IBlock => getApType(object) === 'Block';
|
export const isBlock = (object: IObject): object is IBlock => getApType(object) === 'Block';
|
||||||
export const isFlag = (object: IObject): object is IFlag => getApType(object) === 'Flag';
|
export const isFlag = (object: IObject): object is IFlag => getApType(object) === 'Flag';
|
||||||
export const isMove = (object: IObject): object is IMove => getApType(object) === 'Move';
|
export const isMove = (object: IObject): object is IMove => getApType(object) === 'Move';
|
||||||
|
|
||||||
|
export type PrivateKey = {
|
||||||
|
privateKeyPem: string;
|
||||||
|
keyId: string;
|
||||||
|
};
|
||||||
|
|
|
@ -76,16 +76,14 @@ export class DeliverProcessorService {
|
||||||
await this.fetchInstanceMetadataService.fetchInstanceMetadata(_server).then(() => {});
|
await this.fetchInstanceMetadataService.fetchInstanceMetadata(_server).then(() => {});
|
||||||
const server = await this.federatedInstanceService.fetch(host);
|
const server = await this.federatedInstanceService.fetch(host);
|
||||||
|
|
||||||
/**
|
await this.apRequestService.signedPost(
|
||||||
* RSAキーを強制するかでレベルを変える
|
job.data.user,
|
||||||
*/
|
job.data.to,
|
||||||
const level = job.data.forceMainKey ?
|
job.data.content,
|
||||||
server.httpMessageSignaturesImplementationLevel === '11' ?
|
server.httpMessageSignaturesImplementationLevel,
|
||||||
'10' :
|
job.data.digest,
|
||||||
'00'
|
job.data.privateKey,
|
||||||
: server.httpMessageSignaturesImplementationLevel;
|
);
|
||||||
|
|
||||||
await this.apRequestService.signedPost(job.data.user, job.data.to, job.data.content, level, job.data.digest);
|
|
||||||
|
|
||||||
// Update stats
|
// Update stats
|
||||||
if (server.isNotResponding) {
|
if (server.isNotResponding) {
|
||||||
|
|
|
@ -8,7 +8,7 @@ import type { MiDriveFile } from '@/models/DriveFile.js';
|
||||||
import type { MiNote } from '@/models/Note.js';
|
import type { MiNote } from '@/models/Note.js';
|
||||||
import type { MiUser } from '@/models/User.js';
|
import type { MiUser } from '@/models/User.js';
|
||||||
import type { MiWebhook } from '@/models/Webhook.js';
|
import type { MiWebhook } from '@/models/Webhook.js';
|
||||||
import type { IActivity } from '@/core/activitypub/type.js';
|
import type { IActivity, PrivateKey } from '@/core/activitypub/type.js';
|
||||||
import type { ParsedSignature } from '@misskey-dev/node-http-message-signatures';
|
import type { ParsedSignature } from '@misskey-dev/node-http-message-signatures';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,7 +39,7 @@ export type DeliverJobData = {
|
||||||
/** whether it is sharedInbox */
|
/** whether it is sharedInbox */
|
||||||
isSharedInbox: boolean;
|
isSharedInbox: boolean;
|
||||||
/** force to use main (rsa) key */
|
/** force to use main (rsa) key */
|
||||||
forceMainKey?: boolean;
|
privateKey?: PrivateKey;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type InboxJobData = {
|
export type InboxJobData = {
|
||||||
|
|
Loading…
Reference in a new issue