File size: 3,898 Bytes
4e23b01
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import { mkdtemp, rm } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';

import { afterAll, afterEach, beforeAll, describe, expect, it } from 'vitest';
import { WebSocket, type RawData } from 'ws';

import { type RunningServer, startServer } from '../src/start';
import { TEST_HOST_IDENTITY } from './helpers/hostIdentity';
import { fixedTokenAuth } from './helpers/fixedAuth';

const TOKEN = 'test-token';

function rawToString(data: RawData): string {
  if (typeof data === 'string') return data;
  if (Buffer.isBuffer(data)) return data.toString('utf8');
  if (Array.isArray(data)) return Buffer.concat(data).toString('utf8');
  return Buffer.from(data as ArrayBuffer).toString('utf8');
}

function openConn(url: string): Promise<{ ws: WebSocket; firstFrame: unknown }> {
  return new Promise((resolve, reject) => {
    const ws = new WebSocket(url);
    ws.once('message', (data) => {
      try {
        resolve({ ws, firstFrame: JSON.parse(rawToString(data)) });
      } catch {
        resolve({ ws, firstFrame: null });
      }
    });
    ws.once('error', reject);
  });
}

describe('server-v2 disableAuth (--dangerous-bypass-auth)', () => {
  let server: RunningServer | undefined;
  let home: string | undefined;
  const sockets: WebSocket[] = [];

  beforeAll(async () => {
    home = await mkdtemp(join(tmpdir(), 'kimi-server-v2-disable-auth-'));
    server = await startServer({
      hostIdentity: TEST_HOST_IDENTITY,
      host: '127.0.0.1',
      port: 0,
      homeDir: home,
      logLevel: 'silent',
      authTokenService: fixedTokenAuth(TOKEN),
      disableAuth: true,
    });
  });

  afterEach(() => {
    for (const ws of sockets.splice(0)) {
      try {
        ws.close();
      } catch {
      }
    }
  });

  afterAll(async () => {
    if (server !== undefined) {
      await server.close();
      server = undefined;
    }
    if (home !== undefined) {
      await rm(home, { recursive: true, force: true });
      home = undefined;
    }
  });

  it('disableAuth:true lets REST through without a token and advertises it in /meta', async () => {
    const base = `http://127.0.0.1:${server!.port}`;

    const meta = await fetch(`${base}/api/v1/meta`);
    expect(meta.status).toBe(200);
    const metaBody = (await meta.json()) as {
      code: number;
      data: { dangerous_bypass_auth: boolean };
    };
    expect(metaBody.code).toBe(0);
    expect(metaBody.data.dangerous_bypass_auth).toBe(true);

    const auth = await fetch(`${base}/api/v1/auth`);
    expect(auth.status).toBe(200);
  });

  it('disableAuth:true lets WebSocket upgrades through without a token', async () => {
    const v1 = await openConn(`ws://127.0.0.1:${server!.port}/api/v1/ws`);
    sockets.push(v1.ws);
    expect(v1.firstFrame).toMatchObject({ type: 'server_hello' });
  });

  it('default boot keeps the gate closed and reports dangerous_bypass_auth: false', async () => {
    const altHome = await mkdtemp(join(tmpdir(), 'kimi-server-v2-disable-auth-'));
    const alt = await startServer({
      hostIdentity: TEST_HOST_IDENTITY,
      host: '127.0.0.1',
      port: 0,
      homeDir: altHome,
      logLevel: 'silent',
      authTokenService: fixedTokenAuth(TOKEN),
      disableAuth: undefined,
    });
    try {
      const base = `http://127.0.0.1:${alt.port}`;

      const unauthed = await fetch(`${base}/api/v1/meta`);
      expect(unauthed.status).toBe(401);

      const meta = await fetch(`${base}/api/v1/meta`, {
        headers: { authorization: `Bearer ${TOKEN}` },
      });
      expect(meta.status).toBe(200);
      const metaBody = (await meta.json()) as {
        code: number;
        data: { dangerous_bypass_auth: boolean };
      };
      expect(metaBody.data.dangerous_bypass_auth).toBe(false);
    } finally {
      await alt.close();
      await rm(altHome, { recursive: true, force: true });
    }
  });
});