Skip to content

Commit d1d3b48

Browse files
saschanaztamaina
andauthored
test(backend): restore ap-request tests (#9997)
Co-authored-by: tamaina <[email protected]>
1 parent 8856d68 commit d1d3b48

File tree

3 files changed

+42
-44
lines changed

3 files changed

+42
-44
lines changed

packages/backend/src/core/activitypub/ApRequestService.ts

+34-38
Original file line numberDiff line numberDiff line change
@@ -28,39 +28,23 @@ type PrivateKey = {
2828
keyId: string;
2929
};
3030

31-
@Injectable()
32-
export class ApRequestService {
33-
private logger: Logger;
34-
35-
constructor(
36-
@Inject(DI.config)
37-
private config: Config,
38-
39-
private userKeypairStoreService: UserKeypairStoreService,
40-
private httpRequestService: HttpRequestService,
41-
private loggerService: LoggerService,
42-
) {
43-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
44-
this.logger = this.loggerService?.getLogger('ap-request'); // なぜか TypeError: Cannot read properties of undefined (reading 'getLogger') と言われる
45-
}
46-
47-
@bindThis
48-
private createSignedPost(args: { key: PrivateKey, url: string, body: string, additionalHeaders: Record<string, string> }): Signed {
31+
export class ApRequestCreator {
32+
static createSignedPost(args: { key: PrivateKey, url: string, body: string, additionalHeaders: Record<string, string> }): Signed {
4933
const u = new URL(args.url);
5034
const digestHeader = `SHA-256=${crypto.createHash('sha256').update(args.body).digest('base64')}`;
5135

5236
const request: Request = {
5337
url: u.href,
5438
method: 'POST',
55-
headers: this.objectAssignWithLcKey({
39+
headers: this.#objectAssignWithLcKey({
5640
'Date': new Date().toUTCString(),
5741
'Host': u.host,
5842
'Content-Type': 'application/activity+json',
5943
'Digest': digestHeader,
6044
}, args.additionalHeaders),
6145
};
6246

63-
const result = this.signToRequest(request, args.key, ['(request-target)', 'date', 'host', 'digest']);
47+
const result = this.#signToRequest(request, args.key, ['(request-target)', 'date', 'host', 'digest']);
6448

6549
return {
6650
request,
@@ -70,21 +54,20 @@ export class ApRequestService {
7054
};
7155
}
7256

73-
@bindThis
74-
private createSignedGet(args: { key: PrivateKey, url: string, additionalHeaders: Record<string, string> }): Signed {
57+
static createSignedGet(args: { key: PrivateKey, url: string, additionalHeaders: Record<string, string> }): Signed {
7558
const u = new URL(args.url);
7659

7760
const request: Request = {
7861
url: u.href,
7962
method: 'GET',
80-
headers: this.objectAssignWithLcKey({
63+
headers: this.#objectAssignWithLcKey({
8164
'Accept': 'application/activity+json, application/ld+json',
8265
'Date': new Date().toUTCString(),
8366
'Host': new URL(args.url).host,
8467
}, args.additionalHeaders),
8568
};
8669

87-
const result = this.signToRequest(request, args.key, ['(request-target)', 'date', 'host', 'accept']);
70+
const result = this.#signToRequest(request, args.key, ['(request-target)', 'date', 'host', 'accept']);
8871

8972
return {
9073
request,
@@ -94,13 +77,12 @@ export class ApRequestService {
9477
};
9578
}
9679

97-
@bindThis
98-
private signToRequest(request: Request, key: PrivateKey, includeHeaders: string[]): Signed {
99-
const signingString = this.genSigningString(request, includeHeaders);
80+
static #signToRequest(request: Request, key: PrivateKey, includeHeaders: string[]): Signed {
81+
const signingString = this.#genSigningString(request, includeHeaders);
10082
const signature = crypto.sign('sha256', Buffer.from(signingString), key.privateKeyPem).toString('base64');
10183
const signatureHeader = `keyId="${key.keyId}",algorithm="rsa-sha256",headers="${includeHeaders.join(' ')}",signature="${signature}"`;
10284

103-
request.headers = this.objectAssignWithLcKey(request.headers, {
85+
request.headers = this.#objectAssignWithLcKey(request.headers, {
10486
Signature: signatureHeader,
10587
});
10688
// node-fetch will generate this for us. if we keep 'Host', it won't change with redirects!
@@ -114,9 +96,8 @@ export class ApRequestService {
11496
};
11597
}
11698

117-
@bindThis
118-
private genSigningString(request: Request, includeHeaders: string[]): string {
119-
request.headers = this.lcObjectKey(request.headers);
99+
static #genSigningString(request: Request, includeHeaders: string[]): string {
100+
request.headers = this.#lcObjectKey(request.headers);
120101

121102
const results: string[] = [];
122103

@@ -131,16 +112,31 @@ export class ApRequestService {
131112
return results.join('\n');
132113
}
133114

134-
@bindThis
135-
private lcObjectKey(src: Record<string, string>): Record<string, string> {
115+
static #lcObjectKey(src: Record<string, string>): Record<string, string> {
136116
const dst: Record<string, string> = {};
137117
for (const key of Object.keys(src).filter(x => x !== '__proto__' && typeof src[x] === 'string')) dst[key.toLowerCase()] = src[key];
138118
return dst;
139119
}
140120

141-
@bindThis
142-
private objectAssignWithLcKey(a: Record<string, string>, b: Record<string, string>): Record<string, string> {
143-
return Object.assign(this.lcObjectKey(a), this.lcObjectKey(b));
121+
static #objectAssignWithLcKey(a: Record<string, string>, b: Record<string, string>): Record<string, string> {
122+
return Object.assign(this.#lcObjectKey(a), this.#lcObjectKey(b));
123+
}
124+
}
125+
126+
@Injectable()
127+
export class ApRequestService {
128+
private logger: Logger;
129+
130+
constructor(
131+
@Inject(DI.config)
132+
private config: Config,
133+
134+
private userKeypairStoreService: UserKeypairStoreService,
135+
private httpRequestService: HttpRequestService,
136+
private loggerService: LoggerService,
137+
) {
138+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
139+
this.logger = this.loggerService?.getLogger('ap-request'); // なぜか TypeError: Cannot read properties of undefined (reading 'getLogger') と言われる
144140
}
145141

146142
@bindThis
@@ -149,7 +145,7 @@ export class ApRequestService {
149145

150146
const keypair = await this.userKeypairStoreService.getUserKeypair(user.id);
151147

152-
const req = this.createSignedPost({
148+
const req = ApRequestCreator.createSignedPost({
153149
key: {
154150
privateKeyPem: keypair.privateKey,
155151
keyId: `${this.config.url}/users/${user.id}#main-key`,
@@ -176,7 +172,7 @@ export class ApRequestService {
176172
public async signedGet(url: string, user: { id: User['id'] }) {
177173
const keypair = await this.userKeypairStoreService.getUserKeypair(user.id);
178174

179-
const req = this.createSignedGet({
175+
const req = ApRequestCreator.createSignedGet({
180176
key: {
181177
privateKeyPem: keypair.privateKey,
182178
keyId: `${this.config.url}/users/${user.id}#main-key`,

packages/backend/test/tsconfig.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
},
3838
"compileOnSave": false,
3939
"include": [
40-
"./**/*.ts"
40+
"./**/*.ts",
41+
"../src/@types/**/*.ts",
4142
]
4243
}

packages/backend/test/tests/ap-request.ts renamed to packages/backend/test/unit/ap-request.ts

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
import * as assert from 'assert';
22
import httpSignature from '@peertube/http-signature';
3-
import { genRsaKeyPair } from '../../src/misc/gen-key-pair.js';
4-
import { createSignedPost, createSignedGet } from '../../src/activitypub/ap-request.js';
3+
4+
import { genRsaKeyPair } from '@/misc/gen-key-pair.js';
5+
import { ApRequestCreator } from '@/core/activitypub/ApRequestService.js';
56

67
export const buildParsedSignature = (signingString: string, signature: string, algorithm: string) => {
78
return {
89
scheme: 'Signature',
910
params: {
1011
keyId: 'KeyID', // dummy, not used for verify
1112
algorithm: algorithm,
12-
headers: [ '(request-target)', 'date', 'host', 'digest' ], // dummy, not used for verify
13+
headers: ['(request-target)', 'date', 'host', 'digest'], // dummy, not used for verify
1314
signature: signature,
1415
},
1516
signingString: signingString,
@@ -29,7 +30,7 @@ describe('ap-request', () => {
2930
'User-Agent': 'UA',
3031
};
3132

32-
const req = createSignedPost({ key, url, body, additionalHeaders: headers });
33+
const req = ApRequestCreator.createSignedPost({ key, url, body, additionalHeaders: headers });
3334

3435
const parsed = buildParsedSignature(req.signingString, req.signature, 'rsa-sha256');
3536

@@ -45,7 +46,7 @@ describe('ap-request', () => {
4546
'User-Agent': 'UA',
4647
};
4748

48-
const req = createSignedGet({ key, url, additionalHeaders: headers });
49+
const req = ApRequestCreator.createSignedGet({ key, url, additionalHeaders: headers });
4950

5051
const parsed = buildParsedSignature(req.signingString, req.signature, 'rsa-sha256');
5152

0 commit comments

Comments
 (0)