Merge branch 'develop' into allow-suspended-access
This commit is contained in:
@@ -9,8 +9,16 @@ import * as assert from 'assert';
|
||||
import * as crypto from 'node:crypto';
|
||||
import cbor from 'cbor';
|
||||
import * as OTPAuth from 'otpauth';
|
||||
import { loadConfig } from '../../src/config.js';
|
||||
import { signup, api, post, react, startServer, waitFire } from '../utils.js';
|
||||
import { loadConfig } from '@/config.js';
|
||||
import { api, signup, startServer } from '../utils.js';
|
||||
import type {
|
||||
AuthenticationResponseJSON,
|
||||
AuthenticatorAssertionResponseJSON,
|
||||
AuthenticatorAttestationResponseJSON,
|
||||
PublicKeyCredentialCreationOptionsJSON,
|
||||
PublicKeyCredentialRequestOptionsJSON,
|
||||
RegistrationResponseJSON,
|
||||
} from '@simplewebauthn/typescript-types';
|
||||
import type { INestApplicationContext } from '@nestjs/common';
|
||||
import type * as misskey from 'misskey-js';
|
||||
|
||||
@@ -47,21 +55,20 @@ describe('2要素認証', () => {
|
||||
|
||||
const rpIdHash = (): Buffer => {
|
||||
return crypto.createHash('sha256')
|
||||
.update(Buffer.from(config.hostname, 'utf-8'))
|
||||
.update(Buffer.from(config.host, 'utf-8'))
|
||||
.digest();
|
||||
};
|
||||
|
||||
const keyDoneParam = (param: {
|
||||
token: string,
|
||||
keyName: string,
|
||||
challengeId: string,
|
||||
challenge: string,
|
||||
credentialId: Buffer,
|
||||
creationOptions: PublicKeyCredentialCreationOptionsJSON,
|
||||
}): {
|
||||
attestationObject: string,
|
||||
challengeId: string,
|
||||
clientDataJSON: string,
|
||||
token: string,
|
||||
password: string,
|
||||
name: string,
|
||||
credential: RegistrationResponseJSON,
|
||||
} => {
|
||||
// A COSE encoded public key
|
||||
const credentialPublicKey = cbor.encode(new Map<number, unknown>([
|
||||
@@ -76,7 +83,7 @@ describe('2要素認証', () => {
|
||||
// AuthenticatorAssertionResponse.authenticatorData
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/AuthenticatorAssertionResponse/authenticatorData
|
||||
const credentialIdLength = Buffer.allocUnsafe(2);
|
||||
credentialIdLength.writeUInt16BE(param.credentialId.length);
|
||||
credentialIdLength.writeUInt16BE(param.credentialId.length, 0);
|
||||
const authData = Buffer.concat([
|
||||
rpIdHash(), // rpIdHash(32)
|
||||
Buffer.from([0x45]), // flags(1)
|
||||
@@ -88,20 +95,28 @@ describe('2要素認証', () => {
|
||||
]);
|
||||
|
||||
return {
|
||||
attestationObject: cbor.encode({
|
||||
fmt: 'none',
|
||||
attStmt: {},
|
||||
authData,
|
||||
}).toString('hex'),
|
||||
challengeId: param.challengeId,
|
||||
clientDataJSON: JSON.stringify({
|
||||
type: 'webauthn.create',
|
||||
challenge: param.challenge,
|
||||
origin: config.scheme + '://' + config.host,
|
||||
androidPackageName: 'org.mozilla.firefox',
|
||||
}),
|
||||
password,
|
||||
token: param.token,
|
||||
name: param.keyName,
|
||||
credential: <RegistrationResponseJSON>{
|
||||
id: param.credentialId.toString('base64url'),
|
||||
rawId: param.credentialId.toString('base64url'),
|
||||
response: <AuthenticatorAttestationResponseJSON>{
|
||||
clientDataJSON: Buffer.from(JSON.stringify({
|
||||
type: 'webauthn.create',
|
||||
challenge: param.creationOptions.challenge,
|
||||
origin: config.scheme + '://' + config.host,
|
||||
androidPackageName: 'org.mozilla.firefox',
|
||||
}), 'utf-8').toString('base64url'),
|
||||
attestationObject: cbor.encode({
|
||||
fmt: 'none',
|
||||
attStmt: {},
|
||||
authData,
|
||||
}).toString('base64url'),
|
||||
},
|
||||
clientExtensionResults: {},
|
||||
type: 'public-key',
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@@ -121,17 +136,12 @@ describe('2要素認証', () => {
|
||||
|
||||
const signinWithSecurityKeyParam = (param: {
|
||||
keyName: string,
|
||||
challengeId: string,
|
||||
challenge: string,
|
||||
credentialId: Buffer,
|
||||
requestOptions: PublicKeyCredentialRequestOptionsJSON,
|
||||
}): {
|
||||
authenticatorData: string,
|
||||
credentialId: string,
|
||||
challengeId: string,
|
||||
clientDataJSON: string,
|
||||
username: string,
|
||||
password: string,
|
||||
signature: string,
|
||||
credential: AuthenticationResponseJSON,
|
||||
'g-recaptcha-response'?: string | null,
|
||||
'hcaptcha-response'?: string | null,
|
||||
} => {
|
||||
@@ -144,10 +154,10 @@ describe('2要素認証', () => {
|
||||
]);
|
||||
const clientDataJSONBuffer = Buffer.from(JSON.stringify({
|
||||
type: 'webauthn.get',
|
||||
challenge: param.challenge,
|
||||
challenge: param.requestOptions.challenge,
|
||||
origin: config.scheme + '://' + config.host,
|
||||
androidPackageName: 'org.mozilla.firefox',
|
||||
}));
|
||||
}), 'utf-8');
|
||||
const hashedclientDataJSON = crypto.createHash('sha256')
|
||||
.update(clientDataJSONBuffer)
|
||||
.digest();
|
||||
@@ -156,13 +166,19 @@ describe('2要素認証', () => {
|
||||
.update(Buffer.concat([authenticatorData, hashedclientDataJSON]))
|
||||
.sign(privateKey);
|
||||
return {
|
||||
authenticatorData: authenticatorData.toString('hex'),
|
||||
credentialId: param.credentialId.toString('base64'),
|
||||
challengeId: param.challengeId,
|
||||
clientDataJSON: clientDataJSONBuffer.toString('hex'),
|
||||
username,
|
||||
password,
|
||||
signature: signature.toString('hex'),
|
||||
credential: <AuthenticationResponseJSON>{
|
||||
id: param.credentialId.toString('base64url'),
|
||||
rawId: param.credentialId.toString('base64url'),
|
||||
response: <AuthenticatorAssertionResponseJSON>{
|
||||
clientDataJSON: clientDataJSONBuffer.toString('base64url'),
|
||||
authenticatorData: authenticatorData.toString('base64url'),
|
||||
signature: signature.toString('base64url'),
|
||||
},
|
||||
clientExtensionResults: {},
|
||||
type: 'public-key',
|
||||
},
|
||||
'g-recaptcha-response': null,
|
||||
'hcaptcha-response': null,
|
||||
};
|
||||
@@ -191,7 +207,7 @@ describe('2要素認証', () => {
|
||||
const doneResponse = await api('/i/2fa/done', {
|
||||
token: otpToken(registerResponse.body.secret),
|
||||
}, alice);
|
||||
assert.strictEqual(doneResponse.status, 204);
|
||||
assert.strictEqual(doneResponse.status, 200);
|
||||
|
||||
const usersShowResponse = await api('/users/show', {
|
||||
username,
|
||||
@@ -205,6 +221,12 @@ describe('2要素認証', () => {
|
||||
});
|
||||
assert.strictEqual(signinResponse.status, 200);
|
||||
assert.notEqual(signinResponse.body.i, undefined);
|
||||
|
||||
// 後片付け
|
||||
await api('/i/2fa/unregister', {
|
||||
password,
|
||||
token: otpToken(registerResponse.body.secret),
|
||||
}, alice);
|
||||
});
|
||||
|
||||
test('が設定でき、セキュリティキーでログインできる。', async () => {
|
||||
@@ -216,25 +238,26 @@ describe('2要素認証', () => {
|
||||
const doneResponse = await api('/i/2fa/done', {
|
||||
token: otpToken(registerResponse.body.secret),
|
||||
}, alice);
|
||||
assert.strictEqual(doneResponse.status, 204);
|
||||
assert.strictEqual(doneResponse.status, 200);
|
||||
|
||||
const registerKeyResponse = await api('/i/2fa/register-key', {
|
||||
password,
|
||||
token: otpToken(registerResponse.body.secret),
|
||||
}, alice);
|
||||
assert.strictEqual(registerKeyResponse.status, 200);
|
||||
assert.notEqual(registerKeyResponse.body.challengeId, undefined);
|
||||
assert.notEqual(registerKeyResponse.body.rp, undefined);
|
||||
assert.notEqual(registerKeyResponse.body.challenge, undefined);
|
||||
|
||||
const keyName = 'example-key';
|
||||
const credentialId = crypto.randomBytes(0x41);
|
||||
const keyDoneResponse = await api('/i/2fa/key-done', keyDoneParam({
|
||||
token: otpToken(registerResponse.body.secret),
|
||||
keyName,
|
||||
challengeId: registerKeyResponse.body.challengeId,
|
||||
challenge: registerKeyResponse.body.challenge,
|
||||
credentialId,
|
||||
creationOptions: registerKeyResponse.body,
|
||||
}), alice);
|
||||
assert.strictEqual(keyDoneResponse.status, 200);
|
||||
assert.strictEqual(keyDoneResponse.body.id, credentialId.toString('hex'));
|
||||
assert.strictEqual(keyDoneResponse.body.id, credentialId.toString('base64url'));
|
||||
assert.strictEqual(keyDoneResponse.body.name, keyName);
|
||||
|
||||
const usersShowResponse = await api('/users/show', {
|
||||
@@ -248,19 +271,23 @@ describe('2要素認証', () => {
|
||||
});
|
||||
assert.strictEqual(signinResponse.status, 200);
|
||||
assert.strictEqual(signinResponse.body.i, undefined);
|
||||
assert.notEqual(signinResponse.body.challengeId, undefined);
|
||||
assert.notEqual(signinResponse.body.challenge, undefined);
|
||||
assert.notEqual(signinResponse.body.securityKeys, undefined);
|
||||
assert.strictEqual(signinResponse.body.securityKeys[0].id, credentialId.toString('hex'));
|
||||
assert.notEqual(signinResponse.body.allowCredentials, undefined);
|
||||
assert.strictEqual(signinResponse.body.allowCredentials[0].id, credentialId.toString('base64url'));
|
||||
|
||||
const signinResponse2 = await api('/signin', signinWithSecurityKeyParam({
|
||||
keyName,
|
||||
challengeId: signinResponse.body.challengeId,
|
||||
challenge: signinResponse.body.challenge,
|
||||
credentialId,
|
||||
requestOptions: signinResponse.body,
|
||||
}));
|
||||
assert.strictEqual(signinResponse2.status, 200);
|
||||
assert.notEqual(signinResponse2.body.i, undefined);
|
||||
|
||||
// 後片付け
|
||||
await api('/i/2fa/unregister', {
|
||||
password,
|
||||
token: otpToken(registerResponse.body.secret),
|
||||
}, alice);
|
||||
});
|
||||
|
||||
test('が設定でき、セキュリティキーでパスワードレスログインできる。', async () => {
|
||||
@@ -272,9 +299,10 @@ describe('2要素認証', () => {
|
||||
const doneResponse = await api('/i/2fa/done', {
|
||||
token: otpToken(registerResponse.body.secret),
|
||||
}, alice);
|
||||
assert.strictEqual(doneResponse.status, 204);
|
||||
assert.strictEqual(doneResponse.status, 200);
|
||||
|
||||
const registerKeyResponse = await api('/i/2fa/register-key', {
|
||||
token: otpToken(registerResponse.body.secret),
|
||||
password,
|
||||
}, alice);
|
||||
assert.strictEqual(registerKeyResponse.status, 200);
|
||||
@@ -282,10 +310,10 @@ describe('2要素認証', () => {
|
||||
const keyName = 'example-key';
|
||||
const credentialId = crypto.randomBytes(0x41);
|
||||
const keyDoneResponse = await api('/i/2fa/key-done', keyDoneParam({
|
||||
token: otpToken(registerResponse.body.secret),
|
||||
keyName,
|
||||
challengeId: registerKeyResponse.body.challengeId,
|
||||
challenge: registerKeyResponse.body.challenge,
|
||||
credentialId,
|
||||
creationOptions: registerKeyResponse.body,
|
||||
}), alice);
|
||||
assert.strictEqual(keyDoneResponse.status, 200);
|
||||
|
||||
@@ -310,14 +338,19 @@ describe('2要素認証', () => {
|
||||
const signinResponse2 = await api('/signin', {
|
||||
...signinWithSecurityKeyParam({
|
||||
keyName,
|
||||
challengeId: signinResponse.body.challengeId,
|
||||
challenge: signinResponse.body.challenge,
|
||||
credentialId,
|
||||
requestOptions: signinResponse.body,
|
||||
}),
|
||||
password: '',
|
||||
});
|
||||
assert.strictEqual(signinResponse2.status, 200);
|
||||
assert.notEqual(signinResponse2.body.i, undefined);
|
||||
|
||||
// 後片付け
|
||||
await api('/i/2fa/unregister', {
|
||||
password,
|
||||
token: otpToken(registerResponse.body.secret),
|
||||
}, alice);
|
||||
});
|
||||
|
||||
test('が設定でき、設定したセキュリティキーの名前を変更できる。', async () => {
|
||||
@@ -329,9 +362,10 @@ describe('2要素認証', () => {
|
||||
const doneResponse = await api('/i/2fa/done', {
|
||||
token: otpToken(registerResponse.body.secret),
|
||||
}, alice);
|
||||
assert.strictEqual(doneResponse.status, 204);
|
||||
assert.strictEqual(doneResponse.status, 200);
|
||||
|
||||
const registerKeyResponse = await api('/i/2fa/register-key', {
|
||||
token: otpToken(registerResponse.body.secret),
|
||||
password,
|
||||
}, alice);
|
||||
assert.strictEqual(registerKeyResponse.status, 200);
|
||||
@@ -339,27 +373,33 @@ describe('2要素認証', () => {
|
||||
const keyName = 'example-key';
|
||||
const credentialId = crypto.randomBytes(0x41);
|
||||
const keyDoneResponse = await api('/i/2fa/key-done', keyDoneParam({
|
||||
token: otpToken(registerResponse.body.secret),
|
||||
keyName,
|
||||
challengeId: registerKeyResponse.body.challengeId,
|
||||
challenge: registerKeyResponse.body.challenge,
|
||||
credentialId,
|
||||
creationOptions: registerKeyResponse.body,
|
||||
}), alice);
|
||||
assert.strictEqual(keyDoneResponse.status, 200);
|
||||
|
||||
const renamedKey = 'other-key';
|
||||
const updateKeyResponse = await api('/i/2fa/update-key', {
|
||||
name: renamedKey,
|
||||
credentialId: credentialId.toString('hex'),
|
||||
credentialId: credentialId.toString('base64url'),
|
||||
}, alice);
|
||||
assert.strictEqual(updateKeyResponse.status, 200);
|
||||
|
||||
const iResponse = await api('/i', {
|
||||
}, alice);
|
||||
assert.strictEqual(iResponse.status, 200);
|
||||
const securityKeys = iResponse.body.securityKeysList.filter(s => s.id === credentialId.toString('hex'));
|
||||
const securityKeys = iResponse.body.securityKeysList.filter((s: { id: string; }) => s.id === credentialId.toString('base64url'));
|
||||
assert.strictEqual(securityKeys.length, 1);
|
||||
assert.strictEqual(securityKeys[0].name, renamedKey);
|
||||
assert.notEqual(securityKeys[0].lastUsed, undefined);
|
||||
|
||||
// 後片付け
|
||||
await api('/i/2fa/unregister', {
|
||||
password,
|
||||
token: otpToken(registerResponse.body.secret),
|
||||
}, alice);
|
||||
});
|
||||
|
||||
test('が設定でき、設定したセキュリティキーを削除できる。', async () => {
|
||||
@@ -371,9 +411,10 @@ describe('2要素認証', () => {
|
||||
const doneResponse = await api('/i/2fa/done', {
|
||||
token: otpToken(registerResponse.body.secret),
|
||||
}, alice);
|
||||
assert.strictEqual(doneResponse.status, 204);
|
||||
assert.strictEqual(doneResponse.status, 200);
|
||||
|
||||
const registerKeyResponse = await api('/i/2fa/register-key', {
|
||||
token: otpToken(registerResponse.body.secret),
|
||||
password,
|
||||
}, alice);
|
||||
assert.strictEqual(registerKeyResponse.status, 200);
|
||||
@@ -381,10 +422,10 @@ describe('2要素認証', () => {
|
||||
const keyName = 'example-key';
|
||||
const credentialId = crypto.randomBytes(0x41);
|
||||
const keyDoneResponse = await api('/i/2fa/key-done', keyDoneParam({
|
||||
token: otpToken(registerResponse.body.secret),
|
||||
keyName,
|
||||
challengeId: registerKeyResponse.body.challengeId,
|
||||
challenge: registerKeyResponse.body.challenge,
|
||||
credentialId,
|
||||
creationOptions: registerKeyResponse.body,
|
||||
}), alice);
|
||||
assert.strictEqual(keyDoneResponse.status, 200);
|
||||
|
||||
@@ -394,6 +435,7 @@ describe('2要素認証', () => {
|
||||
assert.strictEqual(iResponse.status, 200);
|
||||
for (const key of iResponse.body.securityKeysList) {
|
||||
const removeKeyResponse = await api('/i/2fa/remove-key', {
|
||||
token: otpToken(registerResponse.body.secret),
|
||||
password,
|
||||
credentialId: key.id,
|
||||
}, alice);
|
||||
@@ -412,6 +454,12 @@ describe('2要素認証', () => {
|
||||
});
|
||||
assert.strictEqual(signinResponse.status, 200);
|
||||
assert.notEqual(signinResponse.body.i, undefined);
|
||||
|
||||
// 後片付け
|
||||
await api('/i/2fa/unregister', {
|
||||
password,
|
||||
token: otpToken(registerResponse.body.secret),
|
||||
}, alice);
|
||||
});
|
||||
|
||||
test('が設定でき、設定解除できる。(パスワードのみでログインできる。)', async () => {
|
||||
@@ -423,7 +471,7 @@ describe('2要素認証', () => {
|
||||
const doneResponse = await api('/i/2fa/done', {
|
||||
token: otpToken(registerResponse.body.secret),
|
||||
}, alice);
|
||||
assert.strictEqual(doneResponse.status, 204);
|
||||
assert.strictEqual(doneResponse.status, 200);
|
||||
|
||||
const usersShowResponse = await api('/users/show', {
|
||||
username,
|
||||
@@ -432,6 +480,7 @@ describe('2要素認証', () => {
|
||||
assert.strictEqual(usersShowResponse.body.twoFactorEnabled, true);
|
||||
|
||||
const unregisterResponse = await api('/i/2fa/unregister', {
|
||||
token: otpToken(registerResponse.body.secret),
|
||||
password,
|
||||
}, alice);
|
||||
assert.strictEqual(unregisterResponse.status, 204);
|
||||
@@ -441,5 +490,11 @@ describe('2要素認証', () => {
|
||||
});
|
||||
assert.strictEqual(signinResponse.status, 200);
|
||||
assert.notEqual(signinResponse.body.i, undefined);
|
||||
|
||||
// 後片付け
|
||||
await api('/i/2fa/unregister', {
|
||||
password,
|
||||
token: otpToken(registerResponse.body.secret),
|
||||
}, alice);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -721,7 +721,7 @@ describe('クリップ', () => {
|
||||
await addNote({ clipId: aliceClip.id, noteId: aliceNote.id });
|
||||
const res = await show({ clipId: aliceClip.id });
|
||||
assert.strictEqual(res.lastClippedAt, new Date(res.lastClippedAt ?? '').toISOString());
|
||||
assert.deepStrictEqual(await notes({ clipId: aliceClip.id }), [aliceNote]);
|
||||
assert.deepStrictEqual((await notes({ clipId: aliceClip.id })).map(x => x.id), [aliceNote.id]);
|
||||
|
||||
// 他人の非公開ノートも突っ込める
|
||||
await addNote({ clipId: aliceClip.id, noteId: bobHomeNote.id });
|
||||
@@ -861,8 +861,8 @@ describe('クリップ', () => {
|
||||
bobNote, bobHomeNote,
|
||||
];
|
||||
assert.deepStrictEqual(
|
||||
res.sort(compareBy(s => s.id)),
|
||||
expects.sort(compareBy(s => s.id)));
|
||||
res.sort(compareBy(s => s.id)).map(x => x.id),
|
||||
expects.sort(compareBy(s => s.id)).map(x => x.id));
|
||||
});
|
||||
|
||||
test('を始端IDとlimitで取得できる。', async () => {
|
||||
@@ -881,8 +881,8 @@ describe('クリップ', () => {
|
||||
// Promise.allで返ってくる配列はID順で並んでないのでソートして厳密比較
|
||||
const expects = [noteList[3], noteList[4], noteList[5]];
|
||||
assert.deepStrictEqual(
|
||||
res.sort(compareBy(s => s.id)),
|
||||
expects.sort(compareBy(s => s.id)));
|
||||
res.sort(compareBy(s => s.id)).map(x => x.id),
|
||||
expects.sort(compareBy(s => s.id)).map(x => x.id));
|
||||
});
|
||||
|
||||
test('をID範囲指定で取得できる。', async () => {
|
||||
@@ -901,8 +901,8 @@ describe('クリップ', () => {
|
||||
// Promise.allで返ってくる配列はID順で並んでないのでソートして厳密比較
|
||||
const expects = [noteList[2], noteList[3]];
|
||||
assert.deepStrictEqual(
|
||||
res.sort(compareBy(s => s.id)),
|
||||
expects.sort(compareBy(s => s.id)));
|
||||
res.sort(compareBy(s => s.id)).map(x => x.id),
|
||||
expects.sort(compareBy(s => s.id)).map(x => x.id));
|
||||
});
|
||||
|
||||
test.todo('Remoteのノートもクリップできる。どうテストしよう?');
|
||||
@@ -911,7 +911,7 @@ describe('クリップ', () => {
|
||||
const bobClip = await create({ isPublic: true }, { user: bob } );
|
||||
await addNote({ clipId: bobClip.id, noteId: aliceNote.id }, { user: bob });
|
||||
const res = await notes({ clipId: bobClip.id });
|
||||
assert.deepStrictEqual(res, [aliceNote]);
|
||||
assert.deepStrictEqual(res.map(x => x.id), [aliceNote.id]);
|
||||
});
|
||||
|
||||
test('はPublicなクリップなら認証なしでも取得できる。(非公開ノートはhideされて返ってくる)', async () => {
|
||||
@@ -928,8 +928,8 @@ describe('クリップ', () => {
|
||||
hiddenNote(aliceFollowersNote), hiddenNote(aliceSpecifiedNote),
|
||||
];
|
||||
assert.deepStrictEqual(
|
||||
res.sort(compareBy(s => s.id)),
|
||||
expects.sort(compareBy(s => s.id)));
|
||||
res.sort(compareBy(s => s.id)).map(x => x.id),
|
||||
expects.sort(compareBy(s => s.id)).map(x => x.id));
|
||||
});
|
||||
|
||||
test.todo('ブロック、ミュートされたユーザーからの設定&取得etc.');
|
||||
|
||||
@@ -9,7 +9,7 @@ import * as assert from 'assert';
|
||||
// node-fetch only supports it's own Blob yet
|
||||
// https://github.com/node-fetch/node-fetch/pull/1664
|
||||
import { Blob } from 'node-fetch';
|
||||
import { User } from '@/models/index.js';
|
||||
import { MiUser } from '@/models/_.js';
|
||||
import { startServer, signup, post, api, uploadFile, simpleGet, initTestDb } from '../utils.js';
|
||||
import type { INestApplicationContext } from '@nestjs/common';
|
||||
import type * as misskey from 'misskey-js';
|
||||
@@ -298,7 +298,7 @@ describe('Endpoints', () => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
|
||||
const connection = await initTestDb(true);
|
||||
const Users = connection.getRepository(User);
|
||||
const Users = connection.getRepository(MiUser);
|
||||
const newBob = await Users.findOneByOrFail({ id: bob.id });
|
||||
assert.strictEqual(newBob.followersCount, 0);
|
||||
assert.strictEqual(newBob.followingCount, 1);
|
||||
@@ -360,7 +360,7 @@ describe('Endpoints', () => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
|
||||
const connection = await initTestDb(true);
|
||||
const Users = connection.getRepository(User);
|
||||
const Users = connection.getRepository(MiUser);
|
||||
const newBob = await Users.findOneByOrFail({ id: bob.id });
|
||||
assert.strictEqual(newBob.followersCount, 0);
|
||||
assert.strictEqual(newBob.followingCount, 0);
|
||||
|
||||
@@ -34,6 +34,8 @@ describe('Webリソース', () => {
|
||||
let aliceGalleryPost: any;
|
||||
let aliceChannel: any;
|
||||
|
||||
let bob: misskey.entities.MeSignup;
|
||||
|
||||
type Request = {
|
||||
path: string,
|
||||
accept?: string,
|
||||
@@ -90,6 +92,8 @@ describe('Webリソース', () => {
|
||||
fileIds: [aliceUploadedFile.body.id],
|
||||
});
|
||||
aliceChannel = await channel(alice, {});
|
||||
|
||||
bob = await signup({ username: 'alice' });
|
||||
}, 1000 * 60 * 2);
|
||||
|
||||
afterAll(async () => {
|
||||
@@ -163,9 +167,15 @@ describe('Webリソース', () => {
|
||||
});
|
||||
|
||||
describe.each([{ path: '/queue' }])('$path', ({ path }) => {
|
||||
test('はログインしないとGETできない。', async () => await notOk({
|
||||
path,
|
||||
status: 401,
|
||||
}));
|
||||
|
||||
test('はadminでなければGETできない。', async () => await notOk({
|
||||
path,
|
||||
status: 500, // FIXME? 403ではない。
|
||||
cookie: cookie(bob),
|
||||
status: 403,
|
||||
}));
|
||||
|
||||
test('はadminならGETできる。', async () => await ok({
|
||||
|
||||
@@ -7,7 +7,7 @@ process.env.NODE_ENV = 'test';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { loadConfig } from '@/config.js';
|
||||
import { User, UsersRepository } from '@/models/index.js';
|
||||
import { MiUser, UsersRepository } from '@/models/_.js';
|
||||
import { jobQueue } from '@/boot/common.js';
|
||||
import { secureRndstr } from '@/misc/secure-rndstr.js';
|
||||
import { uploadFile, signup, startServer, initTestDb, api, sleep, successfulApiCall } from '../utils.js';
|
||||
@@ -42,7 +42,7 @@ describe('Account Move', () => {
|
||||
dave = await signup({ username: 'dave' });
|
||||
eve = await signup({ username: 'eve' });
|
||||
frank = await signup({ username: 'frank' });
|
||||
Users = connection.getRepository(User);
|
||||
Users = connection.getRepository(MiUser);
|
||||
}, 1000 * 60 * 2);
|
||||
|
||||
afterAll(async () => {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
process.env.NODE_ENV = 'test';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { Note } from '@/models/entities/Note.js';
|
||||
import { MiNote } from '@/models/Note.js';
|
||||
import { MAX_NOTE_TEXT_LENGTH } from '@/const.js';
|
||||
import { signup, post, uploadUrl, startServer, initTestDb, api, uploadFile } from '../utils.js';
|
||||
import type { INestApplicationContext } from '@nestjs/common';
|
||||
@@ -22,7 +22,7 @@ describe('Note', () => {
|
||||
beforeAll(async () => {
|
||||
app = await startServer();
|
||||
const connection = await initTestDb(true);
|
||||
Notes = connection.getRepository(Note);
|
||||
Notes = connection.getRepository(MiNote);
|
||||
alice = await signup({ username: 'alice' });
|
||||
bob = await signup({ username: 'bob' });
|
||||
}, 1000 * 60 * 2);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
process.env.NODE_ENV = 'test';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { Following } from '@/models/entities/Following.js';
|
||||
import { MiFollowing } from '@/models/Following.js';
|
||||
import { connectStream, signup, api, post, startServer, initTestDb, waitFire } from '../utils.js';
|
||||
import type { INestApplicationContext } from '@nestjs/common';
|
||||
import type * as misskey from 'misskey-js';
|
||||
@@ -46,7 +46,7 @@ describe('Streaming', () => {
|
||||
beforeAll(async () => {
|
||||
app = await startServer();
|
||||
const connection = await initTestDb(true);
|
||||
Followings = connection.getRepository(Following);
|
||||
Followings = connection.getRepository(MiFollowing);
|
||||
|
||||
ayano = await signup({ username: 'ayano' });
|
||||
kyoko = await signup({ username: 'kyoko' });
|
||||
|
||||
@@ -102,6 +102,7 @@ describe('ユーザー', () => {
|
||||
birthday: user.birthday,
|
||||
lang: user.lang,
|
||||
fields: user.fields,
|
||||
verifiedLinks: user.verifiedLinks,
|
||||
followersCount: user.followersCount,
|
||||
followingCount: user.followingCount,
|
||||
notesCount: user.notesCount,
|
||||
@@ -131,6 +132,7 @@ describe('ユーザー', () => {
|
||||
isBlocked: user.isBlocked ?? false,
|
||||
isMuted: user.isMuted ?? false,
|
||||
isRenoteMuted: user.isRenoteMuted ?? false,
|
||||
notify: user.notify ?? 'none',
|
||||
});
|
||||
};
|
||||
|
||||
@@ -152,6 +154,7 @@ describe('ユーザー', () => {
|
||||
preventAiLearning: user.preventAiLearning,
|
||||
isExplorable: user.isExplorable,
|
||||
isDeleted: user.isDeleted,
|
||||
twoFactorBackupCodesStock: user.twoFactorBackupCodesStock,
|
||||
hideOnlineStatus: user.hideOnlineStatus,
|
||||
hasUnreadSpecifiedNotes: user.hasUnreadSpecifiedNotes,
|
||||
hasUnreadMentions: user.hasUnreadMentions,
|
||||
@@ -368,6 +371,7 @@ describe('ユーザー', () => {
|
||||
assert.strictEqual(response.birthday, null);
|
||||
assert.strictEqual(response.lang, null);
|
||||
assert.deepStrictEqual(response.fields, []);
|
||||
assert.deepStrictEqual(response.verifiedLinks, []);
|
||||
assert.strictEqual(response.followersCount, 0);
|
||||
assert.strictEqual(response.followingCount, 0);
|
||||
assert.strictEqual(response.notesCount, 0);
|
||||
@@ -398,6 +402,7 @@ describe('ユーザー', () => {
|
||||
assert.strictEqual(response.preventAiLearning, true);
|
||||
assert.strictEqual(response.isExplorable, true);
|
||||
assert.strictEqual(response.isDeleted, false);
|
||||
assert.strictEqual(response.twoFactorBackupCodesStock, 'none');
|
||||
assert.strictEqual(response.hideOnlineStatus, false);
|
||||
assert.strictEqual(response.hasUnreadSpecifiedNotes, false);
|
||||
assert.strictEqual(response.hasUnreadMentions, false);
|
||||
@@ -490,7 +495,7 @@ describe('ユーザー', () => {
|
||||
{ parameters: (): object => ({ mutedWords: [] }) },
|
||||
{ parameters: (): object => ({ mutedInstances: ['xxxx.xxxxx'] }) },
|
||||
{ parameters: (): object => ({ mutedInstances: [] }) },
|
||||
{ parameters: (): object => ({ mutingNotificationTypes: ['follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollEnded', 'receiveFollowRequest', 'followRequestAccepted', 'achievementEarned', 'app'] }) },
|
||||
{ parameters: (): object => ({ mutingNotificationTypes: ['note', 'follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollEnded', 'receiveFollowRequest', 'followRequestAccepted', 'achievementEarned', 'app'] }) },
|
||||
{ parameters: (): object => ({ mutingNotificationTypes: [] }) },
|
||||
{ parameters: (): object => ({ emailNotificationTypes: ['mention', 'reply', 'quote', 'follow', 'receiveFollowRequest'] }) },
|
||||
{ parameters: (): object => ({ emailNotificationTypes: [] }) },
|
||||
|
||||
Reference in New Issue
Block a user