@joystick.js/db-canary 0.0.0-canary.2294 → 0.0.0-canary.2296

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,21 +3,17 @@ import net from 'net';
3
3
  import { create_server } from '../../../src/server/index.js';
4
4
  import { encode_message, create_message_parser } from '../../../src/server/lib/tcp_protocol.js';
5
5
  import { initialize_database } from '../../../src/server/lib/query_engine.js';
6
- import { setup_authentication } from '../../../src/server/lib/auth_manager.js';
6
+ import { setup_initial_admin, reset_auth_state } from '../../../src/server/lib/user_auth_manager.js';
7
7
 
8
8
  let server;
9
9
  let port;
10
- let shared_password;
10
+ let admin_username = 'admin';
11
+ let admin_password = 'admin123';
11
12
 
12
13
  test.before(async () => {
13
14
  try {
14
- // Clean up authentication file for fresh tests
15
- try {
16
- const { unlinkSync } = await import('fs');
17
- unlinkSync('authentication.json');
18
- } catch (error) {
19
- // File doesn't exist, which is fine
20
- }
15
+ // Reset auth state
16
+ await reset_auth_state();
21
17
 
22
18
  // Initialize database for testing
23
19
  initialize_database();
@@ -38,17 +34,8 @@ test.before(async () => {
38
34
  });
39
35
  });
40
36
 
41
- // Set up authentication once for all tests
42
- const { client, send, receive, close } = await create_client();
43
- try {
44
- send({ op: 'setup' });
45
- const setup_response = await receive();
46
- if (setup_response.ok === 1 || setup_response.ok === true) {
47
- shared_password = setup_response.password;
48
- }
49
- } finally {
50
- close();
51
- }
37
+ // Set up initial admin user for all tests
38
+ await setup_initial_admin(admin_username, admin_password, 'admin@test.com');
52
39
  } catch (error) {
53
40
  throw error;
54
41
  }
@@ -61,6 +48,9 @@ test.after.always(async () => {
61
48
  server.close(resolve);
62
49
  });
63
50
  }
51
+
52
+ // Clean up auth state
53
+ await reset_auth_state();
64
54
  });
65
55
 
66
56
  const create_client = () => {
@@ -122,8 +112,8 @@ test('production safety - admin stats include comprehensive monitoring', async t
122
112
  const { client, send, receive, close } = await create_client();
123
113
 
124
114
  try {
125
- // Authenticate using shared password
126
- send({ op: 'authentication', data: { password: shared_password } });
115
+ // Authenticate using username and password
116
+ send({ op: 'authentication', data: { username: admin_username, password: admin_password } });
127
117
  const auth_response = await receive();
128
118
  t.is(auth_response.ok, 1);
129
119
 
@@ -187,8 +177,8 @@ test('production safety - request timeout handling', async t => {
187
177
  const { client, send, receive, close } = await create_client();
188
178
 
189
179
  try {
190
- // Authenticate using shared password
191
- send({ op: 'authentication', data: { password: shared_password } });
180
+ // Authenticate using username and password
181
+ send({ op: 'authentication', data: { username: admin_username, password: admin_password } });
192
182
  const auth_response = await receive();
193
183
  t.is(auth_response.ok, 1);
194
184
 
@@ -226,8 +216,8 @@ test('production safety - structured logging for operations', async t => {
226
216
  const { client, send, receive, close } = await create_client();
227
217
 
228
218
  try {
229
- // Authenticate using shared password
230
- send({ op: 'authentication', data: { password: shared_password } });
219
+ // Authenticate using username and password
220
+ send({ op: 'authentication', data: { username: admin_username, password: admin_password } });
231
221
  const auth_response = await receive();
232
222
  t.is(auth_response.ok, 1);
233
223
 
@@ -250,8 +240,8 @@ test('production safety - error handling and categorization', async t => {
250
240
  const { client, send, receive, close } = await create_client();
251
241
 
252
242
  try {
253
- // Authenticate using shared password
254
- send({ op: 'authentication', data: { password: shared_password } });
243
+ // Authenticate using username and password
244
+ send({ op: 'authentication', data: { username: admin_username, password: admin_password } });
255
245
  const auth_response = await receive();
256
246
  t.is(auth_response.ok, 1);
257
247
 
@@ -271,8 +261,8 @@ test('production safety - performance metrics tracking', async t => {
271
261
  const { client, send, receive, close } = await create_client();
272
262
 
273
263
  try {
274
- // Authenticate using shared password
275
- send({ op: 'authentication', data: { password: shared_password } });
264
+ // Authenticate using username and password
265
+ send({ op: 'authentication', data: { username: admin_username, password: admin_password } });
276
266
  const auth_response = await receive();
277
267
  t.is(auth_response.ok, 1);
278
268
 
@@ -298,8 +288,8 @@ test('production safety - memory and resource monitoring', async t => {
298
288
  const { client, send, receive, close } = await create_client();
299
289
 
300
290
  try {
301
- // Authenticate using shared password
302
- send({ op: 'authentication', data: { password: shared_password } });
291
+ // Authenticate using username and password
292
+ send({ op: 'authentication', data: { username: admin_username, password: admin_password } });
303
293
  const auth_response = await receive();
304
294
  t.is(auth_response.ok, 1);
305
295
 
@@ -332,8 +322,8 @@ test('production safety - connection management stats', async t => {
332
322
  const { client, send, receive, close } = await create_client();
333
323
 
334
324
  try {
335
- // Authenticate using shared password
336
- send({ op: 'authentication', data: { password: shared_password } });
325
+ // Authenticate using username and password
326
+ send({ op: 'authentication', data: { username: admin_username, password: admin_password } });
337
327
  const auth_response = await receive();
338
328
  t.is(auth_response.ok, 1);
339
329
 
@@ -2,7 +2,7 @@ import test from 'ava';
2
2
  import fs from 'fs';
3
3
  import net from 'net';
4
4
  import { create_server } from '../../../src/server/index.js';
5
- import { setup_authentication, reset_auth_state } from '../../../src/server/lib/auth_manager.js';
5
+ import { setup_initial_admin, reset_auth_state } from '../../../src/server/lib/user_auth_manager.js';
6
6
  import { initialize_database } from '../../../src/server/lib/query_engine.js';
7
7
  import { encode_message, create_message_parser } from '../../../src/server/lib/tcp_protocol.js';
8
8
 
@@ -11,14 +11,15 @@ const AUTH_FILE_PATH = './settings.db.json';
11
11
  // Shared server instance
12
12
  let shared_server = null;
13
13
  let shared_port = null;
14
- let shared_password = null;
14
+ let admin_username = 'admin';
15
+ let admin_password = 'admin123';
15
16
 
16
17
  test.before(async () => {
17
18
  // Set test environment
18
19
  process.env.NODE_ENV = 'test';
19
20
 
20
21
  // Reset auth state and clean up any existing auth files
21
- reset_auth_state();
22
+ await reset_auth_state();
22
23
  if (fs.existsSync(AUTH_FILE_PATH)) {
23
24
  fs.unlinkSync(AUTH_FILE_PATH);
24
25
  }
@@ -45,6 +46,9 @@ test.before(async () => {
45
46
  }
46
47
  });
47
48
  });
49
+
50
+ // Set up initial admin user
51
+ await setup_initial_admin(admin_username, admin_password, 'admin@test.com');
48
52
  });
49
53
 
50
54
  test.after.always(async () => {
@@ -83,7 +87,7 @@ test.after.always(async () => {
83
87
  }
84
88
 
85
89
  // Reset auth state and clean up auth files
86
- reset_auth_state();
90
+ await reset_auth_state();
87
91
  if (fs.existsSync(AUTH_FILE_PATH)) {
88
92
  try {
89
93
  fs.unlinkSync(AUTH_FILE_PATH);
@@ -98,12 +102,9 @@ test.after.always(async () => {
98
102
  }
99
103
  });
100
104
 
101
- test.beforeEach(() => {
102
- // Reset auth state before each test
103
- reset_auth_state();
104
- if (fs.existsSync(AUTH_FILE_PATH)) {
105
- fs.unlinkSync(AUTH_FILE_PATH);
106
- }
105
+ test.beforeEach(async () => {
106
+ // Ensure admin user is set up for each test
107
+ await setup_initial_admin(admin_username, admin_password, 'admin@test.com');
107
108
  });
108
109
 
109
110
  const create_client = () => {
@@ -146,14 +147,11 @@ const create_client = () => {
146
147
  };
147
148
 
148
149
  test('replication admin operations - get status when disabled', async t => {
149
- // Setup authentication first
150
- const password = setup_authentication();
151
-
152
150
  const { client, send, receive, close } = await create_client();
153
151
 
154
152
  try {
155
- // First authenticate
156
- send({ op: 'authentication', data: { password } });
153
+ // First authenticate with username and password
154
+ send({ op: 'authentication', data: { username: admin_username, password: admin_password } });
157
155
  const auth_response = await receive();
158
156
  t.is(auth_response.ok, 1);
159
157
 
@@ -171,14 +169,11 @@ test('replication admin operations - get status when disabled', async t => {
171
169
  });
172
170
 
173
171
  test('replication integration - basic server functionality works', async t => {
174
- // Setup authentication first
175
- const password = setup_authentication();
176
-
177
172
  const { client, send, receive, close } = await create_client();
178
173
 
179
174
  try {
180
- // First authenticate
181
- send({ op: 'authentication', data: { password } });
175
+ // First authenticate with username and password
176
+ send({ op: 'authentication', data: { username: admin_username, password: admin_password } });
182
177
  const auth_response = await receive();
183
178
  t.is(auth_response.ok, 1);
184
179
 
@@ -200,14 +195,11 @@ test('replication integration - basic server functionality works', async t => {
200
195
  });
201
196
 
202
197
  test('replication integration - database operations work normally', async t => {
203
- // Setup authentication first
204
- const password = setup_authentication();
205
-
206
198
  const { client, send, receive, close } = await create_client();
207
199
 
208
200
  try {
209
- // First authenticate
210
- send({ op: 'authentication', data: { password } });
201
+ // First authenticate with username and password
202
+ send({ op: 'authentication', data: { username: admin_username, password: admin_password } });
211
203
  const auth_response = await receive();
212
204
  t.is(auth_response.ok, 1);
213
205
 
@@ -4,7 +4,7 @@ import fs from 'fs';
4
4
  import { encode as encode_messagepack, decode as decode_messagepack } from 'msgpackr';
5
5
  import { create_server } from '../../../../src/server/index.js';
6
6
  import { initialize_database, get_database, cleanup_database } from '../../../../src/server/lib/query_engine.js';
7
- import { reset_auth_state } from '../../../../src/server/lib/auth_manager.js';
7
+ import { reset_auth_state } from '../../../../src/server/lib/user_auth_manager.js';
8
8
 
9
9
  // Dynamic port allocation
10
10
  let current_port = 4000;
@@ -17,7 +17,7 @@ let port;
17
17
 
18
18
  test.beforeEach(async () => {
19
19
  // Reset auth state
20
- reset_auth_state();
20
+ await reset_auth_state();
21
21
 
22
22
  // Initialize test database and clear it for clean state between tests
23
23
  initialize_database('./test_data');
@@ -51,7 +51,7 @@ test.afterEach(async () => {
51
51
  }
52
52
 
53
53
  // Clean up auth state after each test
54
- reset_auth_state();
54
+ await reset_auth_state();
55
55
 
56
56
  // Clean up database
57
57
  await cleanup_database();
@@ -112,7 +112,41 @@ const send_message = (client, message) => {
112
112
  };
113
113
 
114
114
  const authenticate_client = async (client) => {
115
- // First setup authentication
115
+ // Try to setup initial admin user first (since tests clean database)
116
+ try {
117
+ const setup_admin_response = await send_message(client, {
118
+ op: 'admin',
119
+ data: {
120
+ admin_action: 'setup_initial_admin',
121
+ username: 'admin',
122
+ password: 'admin123',
123
+ email: 'admin@test.com'
124
+ }
125
+ });
126
+
127
+ // If successful or already exists, proceed with authentication
128
+ if (setup_admin_response.ok || setup_admin_response.error?.includes('already exists')) {
129
+ // Now authenticate with username/password
130
+ const auth_response = await send_message(client, {
131
+ op: 'authentication',
132
+ data: {
133
+ username: 'admin',
134
+ password: 'admin123'
135
+ }
136
+ });
137
+
138
+ if (!auth_response.ok) {
139
+ throw new Error(`Authentication failed: ${JSON.stringify(auth_response.error || auth_response)}`);
140
+ }
141
+
142
+ return 'admin123';
143
+ }
144
+ } catch (error) {
145
+ // If admin setup fails, fall back to old setup method for backward compatibility
146
+ console.log('Admin setup failed, trying legacy setup method:', error.message);
147
+ }
148
+
149
+ // Fallback: try legacy setup method
116
150
  const setup_response = await send_message(client, {
117
151
  op: 'setup',
118
152
  data: {}
@@ -127,7 +161,7 @@ const authenticate_client = async (client) => {
127
161
  throw new Error(`Setup response did not contain password: ${JSON.stringify(setup_response)}`);
128
162
  }
129
163
 
130
- // Then authenticate
164
+ // Legacy authentication with just password
131
165
  const auth_response = await send_message(client, {
132
166
  op: 'authentication',
133
167
  data: { password }