@joystick.js/db-canary 0.0.0-canary.2297 → 0.0.0-canary.2298
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.
- package/dist/server/index.js +1 -1
- package/package.json +2 -2
- package/src/server/index.js +17 -0
package/dist/server/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import z from"net";import O from"crypto";import{decode as I}from"msgpackr";import R from"./lib/op_types.js";import w from"./lib/safe_json_parse.js";import{load_settings as m,get_settings as f,get_port_configuration as _}from"./lib/load_settings.js";import{send_error as p}from"./lib/send_response.js";import{start_cluster as C}from"./cluster/index.js";import v from"./lib/logger.js";import{initialize_database as D,cleanup_database as E}from"./lib/query_engine.js";import{create_message_parser as q,encode_message as b}from"./lib/tcp_protocol.js";import{create_connection_manager as A}from"./lib/connection_manager.js";import{shutdown_write_queue as B}from"./lib/write_queue.js";import{get_client_ip as N,is_rate_limited as $,initialize_auth_manager as F,reset_auth_state as P}from"./lib/auth_manager.js";import{set_storage_engine as J,verify_credentials as K,setup_initial_admin as S,initialize_user_auth_manager as j,reset_auth_state as G,get_auth_stats as x}from"./lib/user_auth_manager.js";import{initialize_api_key_manager as M}from"./lib/api_key_manager.js";import{is_development_mode as g,display_development_startup_message as U,warn_undefined_node_env as H}from"./lib/development_mode.js";import{restore_backup as V,start_backup_schedule as W,stop_backup_schedule as Y}from"./lib/backup_manager.js";import{initialize_simple_sync_manager as L,shutdown_simple_sync_manager as Q}from"./lib/simple_sync_manager.js";import{initialize_sync_receiver as X,shutdown_sync_receiver as Z}from"./lib/sync_receiver.js";import{handle_database_operation as ee,handle_admin_operation as te,handle_ping_operation as re}from"./lib/operation_dispatcher.js";import{start_http_server as se,stop_http_server as ne}from"./lib/http_server.js";import{create_recovery_token as oe,initialize_recovery_manager as k,reset_recovery_state as ae}from"./lib/recovery_manager.js";import{has_settings as ie}from"./lib/load_settings.js";const i=new Set;let a=null;const ce=()=>O.randomBytes(16).toString("hex"),_e=e=>e&&e.username&&e.password,d=e=>({ok:0,error:e}),pe=e=>({ok:1,version:"1.0.0",message:"Authentication successful",role:e?.role||"user"}),l=(e,t)=>{const r=b(t);e.write(r),e.end()},c=(e,t)=>{const r=b(t);e.write(r)},ue=async(e,t={})=>{if(!_e(t)){const r=d("Authentication requires username and password");l(e,r);return}try{const r=N(e);if($(r)){const n=d("Too many failed attempts. Please try again later.");l(e,n);return}const s=await K(t.username,t.password,r);if(s.success){i.add(e.id);const n=pe(s.user);c(e,n)}else{const n=d(s.error||"Authentication failed");l(e,n)}}catch{const s=d("Authentication failed");l(e,s)}},de=e=>({ok:1,password:e,message:"Authentication setup completed successfully. Save this password - it will not be shown again."}),h=e=>({ok:0,error:`Setup error: ${e}`}),le=async(e,t={})=>{try{if((await x()).configured){const u=h("Authentication already configured");c(e,u);return}const s=ce(),n=await S("admin",s,"admin@localhost.local");if(!n.success){const u=h(n.error);c(e,u);return}const o=de(s);c(e,o)}catch(r){const s=h(r.message);c(e,s)}},me=(e="")=>{if(!e)throw new Error("Must pass an op type for operation.");return R.includes(e)},fe=e=>w(e),ge=e=>{try{const t=I(e);return typeof t=="string"?w(t):t}catch{return null}},ft=e=>{try{return typeof e=="string"?fe(e):Buffer.isBuffer(e)?ge(e):e}catch{return null}},y=e=>g()?!0:i.has(e.id),he=async(e,t)=>{if(e?.restore_from)try{t.info("Startup restore requested",{backup_filename:e.restore_from});const r=await V(e.restore_from);t.info("Startup restore completed",{backup_filename:e.restore_from,duration_ms:r.duration_ms});const s={...e};delete s.restore_from,process.env.JOYSTICK_DB_SETTINGS=JSON.stringify(s),m(),t.info("Removed restore_from from settings after successful restore")}catch(r){t.error("Startup restore failed",{backup_filename:e.restore_from,error:r.message}),t.info("Continuing with fresh database after restore failure")}},ye=()=>{try{return m(),f()}catch{return null}},we=async e=>{const{tcp_port:t}=_(),r=e?.data_path||`./.joystick/data/joystickdb_${t}`,s=D(r);if(F(),j(),J(s),g())try{const n=await x();(!n.configured||n.user_count===0)&&(await S("admin","password","admin@localhost.local")).success&&(console.log("Development admin user created automatically"),console.log(" Username: admin"),console.log(" Password: password"))}catch(n){console.log("Development admin user creation failed:",n.message)}await M(),k()},ve=e=>{try{L(),e.info("Simple sync manager initialized")}catch(t){e.warn("Failed to initialize simple sync manager",{error:t.message})}},be=e=>{X().then(()=>{e.info("Sync receiver initialized")}).catch(t=>{e.warn("Failed to initialize sync receiver",{error:t.message})})},Se=(e,t)=>{if(e?.s3)try{W(),t.info("Backup scheduling started")}catch(r){t.warn("Failed to start backup scheduling",{error:r.message})}},xe=async(e,t)=>{try{const r=await se(e);return r&&t.info("HTTP server started",{http_port:e}),r}catch(r){return t.warn("Failed to start HTTP server",{error:r.message}),null}},ke=()=>{if(g()){const{tcp_port:e,http_port:t}=_();U(e,t)}else H()},Te=()=>A({max_connections:1e3,idle_timeout:600*1e3,request_timeout:5*1e3}),ze=async(e,t,r,s)=>{a.update_activity(e.id);try{const n=r.parse_messages(t);for(const o of n)await Oe(e,o,t.length,s)}catch(n){s.error("Message parsing failed",{client_id:e.id,error:n.message}),p(e,{message:"Invalid message format"}),e.end()}},Oe=async(e,t,r,s)=>{const n=t,o=n?.op||null;if(!o){p(e,{message:"Missing operation type"});return}if(!me(o)){p(e,{message:"Invalid operation type"});return}const T=a.create_request_timeout(e.id,o);try{await Ie(e,o,n,r)}finally{clearTimeout(T)}},Ie=async(e,t,r,s)=>{const n=r?.data||{};switch(t){case"authentication":await ue(e,n);break;case"setup":await le(e,n);break;case"insert_one":case"update_one":case"delete_one":case"delete_many":case"bulk_write":case"find_one":case"find":case"count_documents":case"create_index":case"drop_index":case"get_indexes":await ee(e,t,n,y,s,a,i);break;case"ping":re(e);break;case"admin":await te(e,n,y,a,i);break;case"reload":await Re(e);break;default:p(e,{message:`Operation ${t} not implemented`})}},Re=async e=>{if(!y(e)){p(e,{message:"Authentication required"});return}try{const t=Ce(),r=await De(),s=Ee(t,r);c(e,s)}catch(t){const r={ok:0,error:`Reload operation failed: ${t.message}`};c(e,r)}},Ce=()=>{try{return f()}catch{return null}},De=async()=>{try{return await m(),f()}catch{return{port:1983,authentication:{}}}},Ee=(e,t)=>({ok:1,status:"success",message:"Configuration reloaded successfully",changes:{port_changed:e?e.port!==t.port:!1,authentication_changed:e?e.authentication?.password_hash!==t.authentication?.password_hash:!1},timestamp:new Date().toISOString()}),qe=(e,t)=>{t.info("Client disconnected",{socket_id:e.id}),i.delete(e.id),a.remove_connection(e.id)},Ae=(e,t,r)=>{r.error("Socket error",{socket_id:e.id,error:t.message}),i.delete(e.id),a.remove_connection(e.id)},Be=(e,t,r)=>{e.on("data",async s=>{await ze(e,s,t,r)}),e.on("end",()=>{qe(e,r)}),e.on("error",s=>{Ae(e,s,r)})},Ne=(e,t)=>{if(!a.add_connection(e))return;const r=q();Be(e,r,t)},$e=()=>async()=>{try{await ne(),Y(),await Q(),await Z(),a&&a.shutdown(),i.clear(),await B(),await new Promise(e=>setTimeout(e,100)),await E(),P(),G(),ae()}catch{}},gt=async()=>{const{create_context_logger:e}=v("server"),t=e(),r=ye();await he(r,t),await we(r),ve(t),be(t),Se(r,t),a=Te();const{http_port:s}=_();await xe(s,t),ke();const n=z.createServer((o={})=>{Ne(o,t)});return n.cleanup=$e(),n},Fe=e=>{try{k();const t=oe();console.log("Emergency Recovery Token Generated"),console.log(`Visit: ${t.url}`),console.log("Token expires in 10 minutes"),e.info("Recovery token generated via CLI",{expires_at:new Date(t.expires_at).toISOString()}),process.exit(0)}catch(t){console.error("Failed to generate recovery token:",t.message),e.error("Recovery token generation failed",{error:t.message}),process.exit(1)}},Pe=()=>{const{tcp_port:e}=_();return{worker_count:process.env.WORKER_COUNT?parseInt(process.env.WORKER_COUNT):void 0,port:e,environment:process.env.NODE_ENV||"development"}},Je=(e,t)=>{const{tcp_port:r,http_port:s}=_(),n=ie();t.info("Starting JoystickDB server...",{workers:e.worker_count||"auto",tcp_port:r,http_port:s,environment:e.environment,has_settings:n,port_source:n?"JOYSTICK_DB_SETTINGS":"default"})};if(import.meta.url===`file://${process.argv[1]}`){const{create_context_logger:e}=v("main"),t=e();process.argv.includes("--generate-recovery-token")&&Fe(t);const r=Pe();Je(r,t),C(r)}export{ue as authentication,me as check_op_type,gt as create_server,ft as parse_data,le as setup};
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@joystick.js/db-canary",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.0-canary.
|
|
5
|
-
"canary_version": "0.0.0-canary.
|
|
4
|
+
"version": "0.0.0-canary.2298",
|
|
5
|
+
"canary_version": "0.0.0-canary.2297",
|
|
6
6
|
"description": "JoystickDB - A minimalist database server for the Joystick framework",
|
|
7
7
|
"main": "./dist/server/index.js",
|
|
8
8
|
"scripts": {
|
package/src/server/index.js
CHANGED
|
@@ -361,6 +361,23 @@ const initialize_server_components = async (settings) => {
|
|
|
361
361
|
initialize_user_auth_manager();
|
|
362
362
|
set_storage_engine(db);
|
|
363
363
|
|
|
364
|
+
// NOTE: Create development admin user using user_auth_manager if in development mode
|
|
365
|
+
if (is_development_mode()) {
|
|
366
|
+
try {
|
|
367
|
+
const auth_stats = await get_auth_stats();
|
|
368
|
+
if (!auth_stats.configured || auth_stats.user_count === 0) {
|
|
369
|
+
const admin_result = await setup_initial_admin('admin', 'password', 'admin@localhost.local');
|
|
370
|
+
if (admin_result.success) {
|
|
371
|
+
console.log('Development admin user created automatically');
|
|
372
|
+
console.log(' Username: admin');
|
|
373
|
+
console.log(' Password: password');
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
} catch (error) {
|
|
377
|
+
console.log('Development admin user creation failed:', error.message);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
364
381
|
await initialize_api_key_manager();
|
|
365
382
|
initialize_recovery_manager();
|
|
366
383
|
};
|