feat(backend): accept OAuth bearer token (#11052)
* feat(backend): accept OAuth bearer token * refactor * Update packages/backend/src/server/api/ApiCallService.ts Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com> * Update packages/backend/src/server/api/ApiCallService.ts Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com> * fix * kind: permission for account moved error * also for suspended error * Update packages/backend/src/server/api/StreamingApiServerService.ts Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com> --------- Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com> Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
This commit is contained in:
parent
d48172e9d1
commit
1b1f82a2e2
6 changed files with 222 additions and 52 deletions
|
@ -1,9 +1,10 @@
|
|||
process.env.NODE_ENV = 'test';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { signup, api, startServer, successfulApiCall, failedApiCall } from '../utils.js';
|
||||
import { signup, api, startServer, successfulApiCall, failedApiCall, uploadFile, waitFire, connectStream } from '../utils.js';
|
||||
import type { INestApplicationContext } from '@nestjs/common';
|
||||
import type * as misskey from 'misskey-js';
|
||||
import { IncomingMessage } from 'http';
|
||||
|
||||
describe('API', () => {
|
||||
let app: INestApplicationContext;
|
||||
|
@ -123,4 +124,100 @@ describe('API', () => {
|
|||
id: 'b0a7f5f8-dc2f-4171-b91f-de88ad238e14',
|
||||
});
|
||||
});
|
||||
|
||||
describe('Authentication header', () => {
|
||||
test('一般リクエスト', async () => {
|
||||
await successfulApiCall({
|
||||
endpoint: '/admin/get-index-stats',
|
||||
parameters: {},
|
||||
user: {
|
||||
token: alice.token,
|
||||
bearer: true,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('multipartリクエスト', async () => {
|
||||
const result = await uploadFile({
|
||||
token: alice.token,
|
||||
bearer: true,
|
||||
});
|
||||
assert.strictEqual(result.status, 200);
|
||||
});
|
||||
|
||||
test('streaming', async () => {
|
||||
const fired = await waitFire(
|
||||
{
|
||||
token: alice.token,
|
||||
bearer: true,
|
||||
},
|
||||
'homeTimeline',
|
||||
() => api('notes/create', { text: 'foo' }, alice),
|
||||
msg => msg.type === 'note' && msg.body.text === 'foo',
|
||||
);
|
||||
assert.strictEqual(fired, true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('tokenエラー応答でWWW-Authenticate headerを送る', () => {
|
||||
describe('invalid_token', () => {
|
||||
test('一般リクエスト', async () => {
|
||||
const result = await api('/admin/get-index-stats', {}, {
|
||||
token: 'syuilo',
|
||||
bearer: true,
|
||||
});
|
||||
assert.strictEqual(result.status, 401);
|
||||
assert.ok(result.headers.get('WWW-Authenticate')?.startsWith('Bearer realm="Misskey", error="invalid_token", error_description'));
|
||||
});
|
||||
|
||||
test('multipartリクエスト', async () => {
|
||||
const result = await uploadFile({
|
||||
token: 'syuilo',
|
||||
bearer: true,
|
||||
});
|
||||
assert.strictEqual(result.status, 401);
|
||||
assert.ok(result.headers.get('WWW-Authenticate')?.startsWith('Bearer realm="Misskey", error="invalid_token", error_description'));
|
||||
});
|
||||
|
||||
test('streaming', async () => {
|
||||
await assert.rejects(connectStream(
|
||||
{
|
||||
token: 'syuilo',
|
||||
bearer: true,
|
||||
},
|
||||
'homeTimeline',
|
||||
() => { },
|
||||
), (err: IncomingMessage) => {
|
||||
assert.strictEqual(err.statusCode, 401);
|
||||
assert.ok(err.headers['www-authenticate']?.startsWith('Bearer realm="Misskey", error="invalid_token", error_description'));
|
||||
return true;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('tokenがないとrealmだけおくる', () => {
|
||||
test('一般リクエスト', async () => {
|
||||
const result = await api('/admin/get-index-stats', {});
|
||||
assert.strictEqual(result.status, 401);
|
||||
assert.strictEqual(result.headers.get('WWW-Authenticate'), 'Bearer realm="Misskey"');
|
||||
});
|
||||
|
||||
test('multipartリクエスト', async () => {
|
||||
const result = await uploadFile();
|
||||
assert.strictEqual(result.status, 401);
|
||||
assert.strictEqual(result.headers.get('WWW-Authenticate'), 'Bearer realm="Misskey"');
|
||||
});
|
||||
});
|
||||
|
||||
test('invalid_request', async () => {
|
||||
const result = await api('/notes/create', { text: true }, {
|
||||
token: alice.token,
|
||||
bearer: true,
|
||||
});
|
||||
assert.strictEqual(result.status, 400);
|
||||
assert.ok(result.headers.get('WWW-Authenticate')?.startsWith('Bearer realm="Misskey", error="invalid_request", error_description'));
|
||||
});
|
||||
|
||||
// TODO: insufficient_scope test (authテストが全然なくて書けない)
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue