update @misskey-dev/node-http-message-signatures
This commit is contained in:
parent
e4f70f017e
commit
a405b62827
|
@ -79,7 +79,7 @@
|
||||||
"@fastify/multipart": "8.1.0",
|
"@fastify/multipart": "8.1.0",
|
||||||
"@fastify/static": "6.12.0",
|
"@fastify/static": "6.12.0",
|
||||||
"@fastify/view": "8.2.0",
|
"@fastify/view": "8.2.0",
|
||||||
"@misskey-dev/node-http-message-signatures": "0.0.0-alpha.11",
|
"@misskey-dev/node-http-message-signatures": "0.0.1",
|
||||||
"@misskey-dev/sharp-read-bmp": "1.2.0",
|
"@misskey-dev/sharp-read-bmp": "1.2.0",
|
||||||
"@misskey-dev/summaly": "5.0.3",
|
"@misskey-dev/summaly": "5.0.3",
|
||||||
"@nestjs/common": "10.3.3",
|
"@nestjs/common": "10.3.3",
|
||||||
|
|
|
@ -28,7 +28,7 @@ type PrivateKey = {
|
||||||
keyId: string;
|
keyId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createSignedPost(args: { level: string; key: PrivateKey; url: string; body: string; additionalHeaders: Record<string, string> }) {
|
export async function createSignedPost(args: { level: string; key: PrivateKey; url: string; body: string; additionalHeaders: Record<string, string> }) {
|
||||||
const u = new URL(args.url);
|
const u = new URL(args.url);
|
||||||
const request: RequestLike = {
|
const request: RequestLike = {
|
||||||
url: u.href,
|
url: u.href,
|
||||||
|
@ -42,10 +42,10 @@ export function createSignedPost(args: { level: string; key: PrivateKey; url: st
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: levelによって処理を分ける
|
// TODO: levelによって処理を分ける
|
||||||
const digestHeader = genRFC3230DigestHeader(args.body);
|
const digestHeader = await genRFC3230DigestHeader(args.body, 'SHA-256');
|
||||||
request.headers['Digest'] = digestHeader;
|
request.headers['Digest'] = digestHeader;
|
||||||
|
|
||||||
const result = signAsDraftToRequest(request, args.key, ['(request-target)', 'date', 'host', 'digest']);
|
const result = await signAsDraftToRequest(request, args.key, ['(request-target)', 'date', 'host', 'digest']);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
request,
|
request,
|
||||||
|
@ -53,7 +53,7 @@ export function createSignedPost(args: { level: string; key: PrivateKey; url: st
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createSignedGet(args: { level: string; key: PrivateKey; url: string; additionalHeaders: Record<string, string> }) {
|
export async function createSignedGet(args: { level: string; key: PrivateKey; url: string; additionalHeaders: Record<string, string> }) {
|
||||||
const u = new URL(args.url);
|
const u = new URL(args.url);
|
||||||
const request: RequestLike = {
|
const request: RequestLike = {
|
||||||
url: u.href,
|
url: u.href,
|
||||||
|
@ -67,7 +67,7 @@ export function createSignedGet(args: { level: string; key: PrivateKey; url: str
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: levelによって処理を分ける
|
// TODO: levelによって処理を分ける
|
||||||
const result = signAsDraftToRequest(request, args.key, ['(request-target)', 'date', 'host', 'accept']);
|
const result = await signAsDraftToRequest(request, args.key, ['(request-target)', 'date', 'host', 'accept']);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
request,
|
request,
|
||||||
|
@ -108,7 +108,7 @@ export class ApRequestService {
|
||||||
public async signedPost(user: { id: MiUser['id'] }, url: string, object: unknown, level: string): Promise<void> {
|
public async signedPost(user: { id: MiUser['id'] }, url: string, object: unknown, level: string): 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);
|
const key = await this.getPrivateKey(user.id, level);
|
||||||
const req = createSignedPost({
|
const req = await createSignedPost({
|
||||||
level,
|
level,
|
||||||
key,
|
key,
|
||||||
url,
|
url,
|
||||||
|
@ -140,7 +140,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.getPrivateKey(user.id, level);
|
||||||
const req = createSignedGet({
|
const req = await createSignedGet({
|
||||||
level,
|
level,
|
||||||
key,
|
key,
|
||||||
url,
|
url,
|
||||||
|
|
|
@ -104,7 +104,7 @@ export class InboxProcessorService {
|
||||||
|
|
||||||
// HTTP-Signatureの検証
|
// HTTP-Signatureの検証
|
||||||
const errorLogger = (ms: any) => this.logger.error(ms);
|
const errorLogger = (ms: any) => this.logger.error(ms);
|
||||||
const httpSignatureValidated = verifyDraftSignature(signature, authUser.key.keyPem, errorLogger);
|
const httpSignatureValidated = await verifyDraftSignature(signature, authUser.key.keyPem, errorLogger);
|
||||||
this.logger.debug('Inbox message validation: ', {
|
this.logger.debug('Inbox message validation: ', {
|
||||||
userId: authUser.user.id,
|
userId: authUser.user.id,
|
||||||
userAcct: Acct.toString(authUser.user),
|
userAcct: Acct.toString(authUser.user),
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as crypto from 'node:crypto';
|
|
||||||
import { IncomingMessage } from 'node:http';
|
import { IncomingMessage } from 'node:http';
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import fastifyAccepts from '@fastify/accepts';
|
import fastifyAccepts from '@fastify/accepts';
|
||||||
|
@ -100,10 +99,10 @@ export class ActivityPubServerService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private inbox(request: FastifyRequest, reply: FastifyReply) {
|
private async inbox(request: FastifyRequest, reply: FastifyReply) {
|
||||||
let signature: ReturnType<typeof parseRequestSignature>;
|
let signature: ReturnType<typeof parseRequestSignature>;
|
||||||
|
|
||||||
const verifyDigest = verifyDigestHeader(request.raw, request.rawBody || '', true);
|
const verifyDigest = await verifyDigestHeader(request.raw, request.rawBody || '', true);
|
||||||
if (!verifyDigest) {
|
if (!verifyDigest) {
|
||||||
reply.code(401);
|
reply.code(401);
|
||||||
return;
|
return;
|
||||||
|
@ -120,13 +119,6 @@ export class ActivityPubServerService {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (signature.value.params.headers.indexOf('host') === -1
|
|
||||||
|| request.headers.host !== this.config.host) {
|
|
||||||
// Host not specified or not match.
|
|
||||||
reply.code(401);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.queueService.inbox(request.body as IActivity, signature);
|
this.queueService.inbox(request.body as IActivity, signature);
|
||||||
|
|
||||||
reply.code(202);
|
reply.code(202);
|
||||||
|
|
|
@ -43,12 +43,12 @@ describe('ap-request', () => {
|
||||||
'User-Agent': 'UA',
|
'User-Agent': 'UA',
|
||||||
};
|
};
|
||||||
|
|
||||||
const req = createSignedPost({ level, key, url, body, additionalHeaders: headers });
|
const req = await createSignedPost({ level, key, url, body, additionalHeaders: headers });
|
||||||
|
|
||||||
const parsed = parseRequestSignature(req.request);
|
const parsed = parseRequestSignature(req.request);
|
||||||
expect(parsed?.version).toBe('draft');
|
expect(parsed?.version).toBe('draft');
|
||||||
if (!parsed) return;
|
if (!parsed) return;
|
||||||
const verify = verifyDraftSignature(parsed.value, keypair.publicKey);
|
const verify = await verifyDraftSignature(parsed.value, keypair.publicKey);
|
||||||
assert.deepStrictEqual(verify, true);
|
assert.deepStrictEqual(verify, true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -62,12 +62,12 @@ describe('ap-request', () => {
|
||||||
'User-Agent': 'UA',
|
'User-Agent': 'UA',
|
||||||
};
|
};
|
||||||
|
|
||||||
const req = createSignedGet({ level, key, url, additionalHeaders: headers });
|
const req = await createSignedGet({ level, key, url, additionalHeaders: headers });
|
||||||
|
|
||||||
const parsed = parseRequestSignature(req.request);
|
const parsed = parseRequestSignature(req.request);
|
||||||
expect(parsed?.version).toBe('draft');
|
expect(parsed?.version).toBe('draft');
|
||||||
if (!parsed) return;
|
if (!parsed) return;
|
||||||
const verify = verifyDraftSignature(parsed.value, keypair.publicKey);
|
const verify = await verifyDraftSignature(parsed.value, keypair.publicKey);
|
||||||
assert.deepStrictEqual(verify, true);
|
assert.deepStrictEqual(verify, true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -111,8 +111,8 @@ importers:
|
||||||
specifier: 8.2.0
|
specifier: 8.2.0
|
||||||
version: 8.2.0
|
version: 8.2.0
|
||||||
'@misskey-dev/node-http-message-signatures':
|
'@misskey-dev/node-http-message-signatures':
|
||||||
specifier: 0.0.0-alpha.11
|
specifier: 0.0.1
|
||||||
version: 0.0.0-alpha.11
|
version: 0.0.1
|
||||||
'@misskey-dev/sharp-read-bmp':
|
'@misskey-dev/sharp-read-bmp':
|
||||||
specifier: 1.2.0
|
specifier: 1.2.0
|
||||||
version: 1.2.0
|
version: 1.2.0
|
||||||
|
@ -4621,6 +4621,10 @@ packages:
|
||||||
resolution: {integrity: sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==}
|
resolution: {integrity: sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@lapo/asn1js@1.2.4:
|
||||||
|
resolution: {integrity: sha512-mdInpQZaYUWu5QbKIB2+Vd+j6Y7cc6xQYNwYBPC9jri2rwy3tbxom0IhhT4G5WOKWO7Iht10SxYpKq+AfuH6dw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@levischuck/tiny-cbor@0.2.2:
|
/@levischuck/tiny-cbor@0.2.2:
|
||||||
resolution: {integrity: sha512-f5CnPw997Y2GQ8FAvtuVVC19FX8mwNNC+1XJcIi16n/LTJifKO6QBgGLgN3YEmqtGMk17SKSuoWES3imJVxAVw==}
|
resolution: {integrity: sha512-f5CnPw997Y2GQ8FAvtuVVC19FX8mwNNC+1XJcIi16n/LTJifKO6QBgGLgN3YEmqtGMk17SKSuoWES3imJVxAVw==}
|
||||||
dev: false
|
dev: false
|
||||||
|
@ -4750,8 +4754,10 @@ packages:
|
||||||
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)
|
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@misskey-dev/node-http-message-signatures@0.0.0-alpha.11:
|
/@misskey-dev/node-http-message-signatures@0.0.1:
|
||||||
resolution: {integrity: sha512-DeLzSIquddDQp+hqD9/zS/IkpJg8Zs1h/4viavCFe37CW2W4ABFumXhYJPB07n775QEihZNuvdipoMNXl83jzw==}
|
resolution: {integrity: sha512-BaMYEOSBwBtDW0NJcljE4S39gFpgNigVzbVFlVsKzu4+k7snL72mXEaAoMCHWCw7XmdY3+fKADbQoqc4SFrpLw==}
|
||||||
|
dependencies:
|
||||||
|
'@lapo/asn1js': 1.2.4
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@misskey-dev/sharp-read-bmp@1.2.0:
|
/@misskey-dev/sharp-read-bmp@1.2.0:
|
||||||
|
@ -6641,7 +6647,7 @@ packages:
|
||||||
ts-dedent: 2.2.0
|
ts-dedent: 2.2.0
|
||||||
type-fest: 2.19.0
|
type-fest: 2.19.0
|
||||||
vue: 3.4.21(typescript@5.3.3)
|
vue: 3.4.21(typescript@5.3.3)
|
||||||
vue-component-type-helpers: 1.8.27
|
vue-component-type-helpers: 2.0.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- encoding
|
- encoding
|
||||||
- supports-color
|
- supports-color
|
||||||
|
@ -19440,6 +19446,10 @@ packages:
|
||||||
resolution: {integrity: sha512-6bnLkn8O0JJyiFSIF0EfCogzeqNXpnjJ0vW/SZzNHfe6sPx30lTtTXlE5TFs2qhJlAtDFybStVNpL73cPe3OMQ==}
|
resolution: {integrity: sha512-6bnLkn8O0JJyiFSIF0EfCogzeqNXpnjJ0vW/SZzNHfe6sPx30lTtTXlE5TFs2qhJlAtDFybStVNpL73cPe3OMQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/vue-component-type-helpers@2.0.3:
|
||||||
|
resolution: {integrity: sha512-dVPXmrwul+lLt2ErNqwfIGTWkZoPQjlarFx5pwXnCwdJ80ZaJ2nmqtt3KcUgVaKBwBQBpJqOlJPaMxICBay+Cg==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/vue-demi@0.14.7(vue@3.4.21):
|
/vue-demi@0.14.7(vue@3.4.21):
|
||||||
resolution: {integrity: sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==}
|
resolution: {integrity: sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
Loading…
Reference in New Issue