nanka meccha kaeta

This commit is contained in:
tamaina 2024-03-05 12:55:30 +00:00
parent e4fea42436
commit 021801c721
8 changed files with 31 additions and 40 deletions

View File

@ -84,7 +84,7 @@ export class QueueService {
digest: await genRFC3230DigestHeader(contentBody, 'SHA-256'), digest: await genRFC3230DigestHeader(contentBody, 'SHA-256'),
to, to,
isSharedInbox, isSharedInbox,
privateKey, privateKey: privateKey && { keyId: privateKey.keyId, privateKey: privateKey.privateKey },
}; };
return this.deliverQueue.add(to, data, { return this.deliverQueue.add(to, data, {
@ -126,7 +126,7 @@ export class QueueService {
content: contentBody, content: contentBody,
to: d[0], to: d[0],
isSharedInbox: d[1], isSharedInbox: d[1],
privateKey, privateKey: privateKey && { keyId: privateKey.keyId, privateKey: privateKey.privateKey },
} as DeliverJobData, } as DeliverJobData,
opts, opts,
}))); })));

View File

@ -16,7 +16,8 @@ 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'; import { UserKeypairService } from './UserKeypairService.js';
import type { PrivateKey } from './activitypub/type.js';
const ACTOR_USERNAME = 'relay.actor' as const; const ACTOR_USERNAME = 'relay.actor' as const;
@ -35,6 +36,7 @@ export class RelayService {
private queueService: QueueService, private queueService: QueueService,
private createSystemUserService: CreateSystemUserService, private createSystemUserService: CreateSystemUserService,
private apRendererService: ApRendererService, private apRendererService: ApRendererService,
private userKeypairService: UserKeypairService,
) { ) {
this.relaysCache = new MemorySingleCache<MiRelay[]>(1000 * 60 * 10); this.relaysCache = new MemorySingleCache<MiRelay[]>(1000 * 60 * 10);
} }
@ -122,11 +124,9 @@ export class RelayService {
const copy = deepClone(activity); const copy = deepClone(activity);
if (!copy.to) copy.to = ['https://www.w3.org/ns/activitystreams#Public']; if (!copy.to) copy.to = ['https://www.w3.org/ns/activitystreams#Public'];
privateKey = privateKey ?? await this.userKeypairService.getLocalUserKeypairWithKeyId(user.id);
const signed = await this.apRendererService.attachLdSignature(copy, user, privateKey);
const signed = await this.apRendererService.attachLdSignature(copy, user); this.queueService.deliverMany(user, signed, new Map(relays.map(({ inbox }) => [inbox, false])), privateKey);
for (const relay of relays) {
this.queueService.deliver(user, signed, relay.inbox, false, privateKey);
}
} }
} }

View File

@ -32,8 +32,8 @@ export class UserSuspendService {
const manager = this.apDeliverManagerService.createDeliverManager(user, content); const manager = this.apDeliverManagerService.createDeliverManager(user, content);
manager.addAllKnowingSharedInboxRecipe(); manager.addAllKnowingSharedInboxRecipe();
// process delivre時にはキーペアが消去されているはずなので、ここで挿入する // process delivre時にはキーペアが消去されているはずなので、ここで挿入する
const keypairs = await this.userKeypairService.getLocalUserKeypairWithKeyId(user.id, 'main'); const privateKey = await this.userKeypairService.getLocalUserKeypairWithKeyId(user.id, 'main');
manager.execute({ privateKey: { keyId: keypairs.keyId, privateKeyPem: keypairs.privateKey } }); manager.execute({ privateKey });
} }
} }
@ -46,8 +46,8 @@ export class UserSuspendService {
const manager = this.apDeliverManagerService.createDeliverManager(user, content); const manager = this.apDeliverManagerService.createDeliverManager(user, content);
manager.addAllKnowingSharedInboxRecipe(); manager.addAllKnowingSharedInboxRecipe();
// process delivre時にはキーペアが消去されているはずなので、ここで挿入する // process delivre時にはキーペアが消去されているはずなので、ここで挿入する
const keypairs = await this.userKeypairService.getLocalUserKeypairWithKeyId(user.id, 'main'); const privateKey = await this.userKeypairService.getLocalUserKeypairWithKeyId(user.id, 'main');
manager.execute({ privateKey: { keyId: keypairs.keyId, privateKeyPem: keypairs.privateKey } }); manager.execute({ privateKey });
} }
} }
} }

View File

@ -140,7 +140,7 @@ class DeliverManager {
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`);
// リモートに配信 // リモートに配信
const keyPair = await this.userKeypairService.getLocalUserKeypairWithKeyId(created, 'main'); const keyPair = await this.userKeypairService.getLocalUserKeypairWithKeyId(created, 'main');
await this.accountUpdateService.publishToFollowers(this.actor.id, { keyId: keyPair.keyId, privateKeyPem: keyPair.privateKey }); await this.accountUpdateService.publishToFollowers(this.actor.id, keyPair);
} }
} }
//#endregion //#endregion

View File

@ -30,7 +30,7 @@ import { isNotNull } from '@/misc/is-not-null.js';
import { IdService } from '@/core/IdService.js'; import { IdService } from '@/core/IdService.js';
import { LdSignatureService } from './LdSignatureService.js'; import { LdSignatureService } from './LdSignatureService.js';
import { ApMfmService } from './ApMfmService.js'; import { ApMfmService } from './ApMfmService.js';
import type { IAccept, IActivity, IAdd, IAnnounce, IApDocument, IApEmoji, IApHashtag, IApImage, IApMention, IBlock, ICreate, IDelete, IFlag, IFollow, IKey, ILike, IMove, IObject, IPost, IQuestion, IReject, IRemove, ITombstone, IUndo, IUpdate } from './type.js'; import type { IAccept, IActivity, IAdd, IAnnounce, IApDocument, IApEmoji, IApHashtag, IApImage, IApMention, IBlock, ICreate, IDelete, IFlag, IFollow, IKey, ILike, IMove, IObject, IPost, IQuestion, IReject, IRemove, ITombstone, IUndo, IUpdate, PrivateKey } from './type.js';
@Injectable() @Injectable()
export class ApRendererService { export class ApRendererService {
@ -657,12 +657,10 @@ export class ApRendererService {
} }
@bindThis @bindThis
public async attachLdSignature(activity: any, user: { id: MiUser['id']; host: null; }): Promise<IActivity> { public async attachLdSignature(activity: any, user: { id: MiUser['id']; host: null; }, key: PrivateKey): Promise<IActivity> {
const keypair = await this.userKeypairService.getUserKeypair(user.id);
const ldSignature = this.ldSignatureService.use(); const ldSignature = this.ldSignatureService.use();
ldSignature.debug = false; ldSignature.debug = false;
activity = await ldSignature.signRsaSignature2017(activity, keypair.privateKey, `${this.config.url}/users/${user.id}#main-key`); activity = await ldSignature.signRsaSignature2017(activity, key.privateKey, key.keyId);
return activity; return activity;
} }

View File

@ -34,7 +34,11 @@ export async function createSignedPost(args: { level: string; key: PrivateKey; u
const digestHeader = args.digest ?? await genRFC3230DigestHeader(args.body, 'SHA-256'); const digestHeader = args.digest ?? await genRFC3230DigestHeader(args.body, 'SHA-256');
request.headers['Digest'] = digestHeader; request.headers['Digest'] = digestHeader;
const result = await signAsDraftToRequest(request, args.key, ['(request-target)', 'date', 'host', 'digest']); const result = await signAsDraftToRequest(
request,
{ keyId: args.key.keyId, privateKeyPem: args.key.privateKey },
['(request-target)', 'date', 'host', 'digest'],
);
return { return {
request, request,
@ -56,7 +60,11 @@ export async function createSignedGet(args: { level: string; key: PrivateKey; ur
}; };
// TODO: httpMessageSignaturesImplementationLevelによって新規格で通信をするようにする // TODO: httpMessageSignaturesImplementationLevelによって新規格で通信をするようにする
const result = await signAsDraftToRequest(request, args.key, ['(request-target)', 'date', 'host', 'accept']); const result = await signAsDraftToRequest(
request,
{ keyId: args.key.keyId, privateKeyPem: args.key.privateKey },
['(request-target)', 'date', 'host', 'accept'],
);
return { return {
request, request,
@ -80,25 +88,10 @@ export class ApRequestService {
this.logger = this.loggerService?.getLogger('ap-request'); // なぜか TypeError: Cannot read properties of undefined (reading 'getLogger') と言われる this.logger = this.loggerService?.getLogger('ap-request'); // なぜか TypeError: Cannot read properties of undefined (reading 'getLogger') と言われる
} }
/**
* Get private key by user id and implementation level
* @param userId User id
* @param level Implementation level
*/
@bindThis
private async getPrivateKey(userId: MiUser['id'], level: string): Promise<PrivateKey> {
const keypair = await this.userKeypairService.getLocalUserKeypairWithKeyId(userId, level);
return {
keyId: keypair.keyId,
privateKeyPem: keypair.privateKey,
};
}
@bindThis @bindThis
public async signedPost(user: { id: MiUser['id'] }, url: string, object: unknown, level: string, digest?: string, key?: PrivateKey): 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);
key = key ?? await this.getPrivateKey(user.id, level); key = key ?? await this.userKeypairService.getLocalUserKeypairWithKeyId(user.id, level);
const req = await createSignedPost({ const req = await createSignedPost({
level, level,
key, key,
@ -131,7 +124,7 @@ export class ApRequestService {
*/ */
@bindThis @bindThis
public async signedGet(url: string, user: { id: MiUser['id'] }, level: string): Promise<unknown> { public async signedGet(url: string, user: { id: MiUser['id'] }, level: string): Promise<unknown> {
const key = await this.getPrivateKey(user.id, level); const key = await this.userKeypairService.getLocalUserKeypairWithKeyId(user.id, level);
const req = await createSignedGet({ const req = await createSignedGet({
level, level,
key, key,

View File

@ -328,6 +328,6 @@ export const isFlag = (object: IObject): object is IFlag => getApType(object) ==
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 = { export type PrivateKey = {
privateKeyPem: string; privateKey: string;
keyId: string; keyId: string;
}; };

View File

@ -35,7 +35,7 @@ describe('ap-request', () => {
describe.each(['00', '01'])('createSignedPost with verify', (level) => { describe.each(['00', '01'])('createSignedPost with verify', (level) => {
test('pass', async () => { test('pass', async () => {
const keypair = await getKeyPair(level); const keypair = await getKeyPair(level);
const key = { keyId: 'x', 'privateKeyPem': keypair.privateKey }; const key = { keyId: 'x', 'privateKey': keypair.privateKey };
const url = 'https://example.com/inbox'; const url = 'https://example.com/inbox';
const activity = { a: 1 }; const activity = { a: 1 };
const body = JSON.stringify(activity); const body = JSON.stringify(activity);
@ -56,7 +56,7 @@ describe('ap-request', () => {
describe.each(['00', '01'])('createSignedGet with verify', (level) => { describe.each(['00', '01'])('createSignedGet with verify', (level) => {
test('pass', async () => { test('pass', async () => {
const keypair = await getKeyPair(level); const keypair = await getKeyPair(level);
const key = { keyId: 'x', 'privateKeyPem': keypair.privateKey }; const key = { keyId: 'x', 'privateKey': keypair.privateKey };
const url = 'https://example.com/outbox'; const url = 'https://example.com/outbox';
const headers = { const headers = {
'User-Agent': 'UA', 'User-Agent': 'UA',