From 4047c52f2d8aa8f1ffceb65fe7c2bbc5b2513412 Mon Sep 17 00:00:00 2001 From: Rory& Date: Thu, 4 Dec 2025 11:01:06 +0100 Subject: [PATCH] validate that endpoitns are configured --- assets/openapi.json | Bin 846379 -> 856837 bytes assets/schemas.json | Bin 371470 -> 380401 bytes src/util/util/Config.ts | 39 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/assets/openapi.json b/assets/openapi.json index 5d4613642488fe83ff508796a920dd34f82dd304..6bf6f92257c279976a31c58e2fa0c47d84a33b55 100644 GIT binary patch delta 2489 zcmds3duUT<6zAOUem6;zx*K0j(x#8pw?^Zm^;xa1KC08jwZ2x=+$7g}NAqYNqT6sP z6Lq4de$q1-V$0CsMCN0X*$tNN!N6@AVIULKDua!|KsQj>knOukP3sW$-v;~R!2Qm5 zzVrN@bMBe%rtdv9QjQN%tME6!zVctD4Jq_dZJBg((81UQ(;_AE(E=YV@f!_MUA-^hXawI7RK(+=wx=^;x?~$ujHs}O@`gg>_OWUoi}_C zPYv<2UYAU$XIh8o5 zYe_5;V%DT>5TM%+gZ&AhJu%`WuBIfj_LLDQKEpL0o9# z6))=}7JPBLR3h>Q2(sN>j)COqAlFq4c{+J`-7J;l;Awo4W~`q{N22F#v2u8>?c%GG zYEo@V@I=QKdK26lWhuH_%KPd_-0&vlEaz9)QaAuFotDMSKv9nXuv<4XnCHm zw++f?1=lkh$2U``9(3`~(B}^f%>Bp6+#@j=PH6Z5EY+yv8+}%T12fGWW2pvE@}BJd z2yB?CqeaH}=Aaf={B77h&0xb+BZ!#sh*M}_s~SwQ?$^fiE?D)yh-x`(l47b}C_KMc zvSH=-W=ev|T;#)9=JSdXNxu>ZM0om|I9#-F>kC>)OJGMcs5t3eX&R<((dq2XGrWc- zm`|f>OpD;|S#S`ux2c4`IlzvNlajOl=57s4wew+I(D{^Fea`dI8wjXzws6GQ&UYlW z|A>5UPm>Gp8dQ$Z$PQhe<9jsg6Wf^Y3LjZEp+XKMv~9dS8zOvlgjc8qsob8xuH%v@ zL}J+M7xd<=p=z5NNMO4ljbq;JHF)6=aj~dqV)FhCDBpxJm~~3a@QY)l3{M=Fs2GXy z_1Vi~vN0g|B?Tum! zE|?1|`A$ubm;*y0mmP>=$ERi+*3E_D^qsk|b7sNxCcJu&jLN4zyGQivMyIjVt8UB` z6A6#}L~f=(Nx}`PJ7y8Mqw8?<0ihc`d&TwX$!`hE0evZvri*q%q_i+H7Nh3?v0;4= z7%?h{FQe}=48c1f?oWHKf>*%IJYfaa6VZkztYi!Ba!Ov^=jS@%9vm&VrN8|UQ~~8M znDAT+%t3FlXhB1lp$vUCVHwKTc+XdK(3*7DDd^#QtbbJft9Bm&Mn8t4^qwC0xw??i zLB-t1bH+*FL^z2&hxB2T)Xtv8;PhnuKV*XbQ;?1{OTUyrEn5B3L3|vNp3_D2Q;;uu zr@mL~^24zHYce4xAk@yr_DQ4?kF1f5`)b2dx;AV$eFmd-hEe-2JB*x6oQgP^)0Z8V H*tNd^B|~M_ delta 543 zcmbV|K}b|l7=`)YyZ62~<0A((RGhJqHm1WkTJ#1fnh*rVg&?AaHG|?Vc$45(6Ow^y zKzQ*ExF~ZG)I?4S-f|J+MhKE-;UYr8h2bWc1ksh$9ig^?ix1A?od5isxmVY6+gJ0w zp;f&*cz|#xZ%540hEZ6e4lFj(kUWi&ry+e;e35BOi*p1HS z)(0B&8i~vMHjTB)(l}KS5+PoXr{mP;hEqLd;g`+?P21(Fdq_qoH{ahxU_?`w=pn6K1*$d9rn6mMt&_f|ZyHZ6YEQXID* zi6_WHRQ|P=4Vb^EN3pkS`OrVYLP)KdysQRLJkndv?7AI`xw8+#2+s&3vk4(LVZ6?v Wf71G%al1@~PvKWoNVm(H{Q3t3(!-em diff --git a/assets/schemas.json b/assets/schemas.json index e73e88c8869589d133f9b0526651af365a57469e..4d3646d61a7222806358ed1aed3f8c95bda7fbe8 100644 GIT binary patch delta 2247 zcmdT_Yitx%6wbXfcORv;Tes}e0_}EbD+Q)(6L}dPTe^$#C{EK-YIt?py|e?nv)i3n zUJ0-W5z}C$+}LBZij5&k4AO#OO(3QQH717Inm`EgM{D8_ObCS^{xAaGS<03GCj2u_ zGBfv{*FE=~@0`}wts%8)gi5UYgBfhJN+R`%mK_vE&Ile;2RB5ay8_h+R13ja zJqo~}4bO(=O{fe$J|PrKn(Mg=?$GFz0|jR+tIc~y{NVHhAN2);$a8t58AOIUJQ z0XvRu%y()YtUoMRz!%2(;HgB*z_A5;Y^@W1LteH}!J7ZB0N>lfbW;UZ91*~_h&NyUsaI2i{`N5TV&FDT?!Y&_yy4d@?k-Q;g5tI z7@i{Jf&Yj=VBZ$;;g&^ydI7RaNj5hpg0Bj>z#qirJwxa<$d$3xDybnUqQqGDm#f(F zxlR}#$J3Z&K?xgnTZz<8l@L=BCCm}?!(cHkGh<-7Cie8_UfjMcQIVU9oG_3C8hpvP>0_mItB^z7eTx8r82O;`#(Tv@Cz2w;}qZTuU^x*9=nlnGAjtRbzv0w>_O4Zq5q>He3k4-6Xd~ z=P;-7Clxc1ewNh?^HJ34zp5K_j{((%s0n;KG0D~I5;Q^U4W25!T3&5dEs4{%L>Rg^ zBMFFIy*16L40-sm~OQtN$+OV?0D}*)u@(}YPH=+V6CGHI9nS6FP+|#+;@s~)JUEdZ` zb)_XtS>Ht`JAR{>w6@bw0!9L;a;IxT(7H)u#9`Jw7(c$<}+~5pQ<-hmh zyvMcYG86;q1y3RFgp=3ASuk9NcU*W6730*wYSfF&?w5*IU>}CF`$;=AyTyEXFqQZJ z+r20keqPHz`(>oV?IKLh$A8;Y29;|?3kw~~=c95yjCJxcV=nq_Xlaj(9WZ1?BM_TS zHVQG-3ny)8dTPBLxvDabltA)~Sf2Xg6|~r5I#F9_miJO{{D~ZptVRT4?Lx3;M6jnk zn^D*T2NocEYP1Diw?3y}5<@b9vQmu(V#S$rpDzFp{t&Ei|1i&@>f<&WmKIq2q_T`Bcz6S?O^3!#b<9cm*a*Az8(4Iua70^WAq%yY90Ja@1+ U!)G1#X>jEYVohz*$oZxJ0GHJO+3JsGqWV z{r@Db>94dHFHLut$S5#2tLhdA1wsFp3$%jF6oiz@a*wua=o@dP5Pj z*yIPCI@1+WSXieWU}TxR_lM(j|KH47lQ;0nPhYTyiDf%SJYy6qk~Om#r$0zz%$(lv zjM;Dc0v{&r?Lh8%@#z<)F>-Ey-^;k2ZTf?`EH={vo-qkdpD>x(Zu_rR#)a(oSmqyKHa9TX?pV!QEi&D40&D2>hBj9D z=>`*6`9TuX8yi?dCfSQlesEHH@&p~#=^vIdE5T(a7jjBW-%!KKzTIvj>t-7O=cSP! diff --git a/src/util/util/Config.ts b/src/util/util/Config.ts index 2fd9c0fb7..a79c908d7 100644 --- a/src/util/util/Config.ts +++ b/src/util/util/Config.ts @@ -54,7 +54,9 @@ export class Config { config = OrmUtils.mergeDeep({}, { ...new ConfigValue() }, config); - return this.set(config); + await this.set(config); + validateFinalConfig(config); + return config; }; public static get() { if (!config) { @@ -169,3 +171,38 @@ const validateConfig = async () => { return config; }; + +function validateFinalConfig(config: ConfigValue) { + let hasErrors = false; + function assertConfig(path: string, condition: (val: any) => boolean, recommendedValue: string) { + // _ to separate keys + const keys = path.split("_"); + let obj: any = config; + + for (const key of keys) { + if (obj == null || !(key in obj)) { + console.warn(`[Config] Missing config value for '${path}'. Recommended value: ${recommendedValue}`); + return; + } + obj = obj[key]; + } + + if (!condition(obj)) { + console.warn(`[Config] Invalid config value for '${path}': ${obj}. Recommended value: ${recommendedValue}`); + hasErrors = true; + } + } + + assertConfig("api_endpointPublic", v => v != null, "A valid public API endpoint URL, ex. \"http://localhost:3001/api/v9\""); + assertConfig("cdn_endpointPublic", v => v != null, "A valid public CDN endpoint URL, ex. \"http://localhost:3002/\""); + assertConfig("cdn_endpointPrivate", v => v != null, "A valid private CDN endpoint URL, ex. \"http://localhost:3002/\" - must be routable from the API server!"); + assertConfig("gateway_endpointPublic", v => v != null, "A valid public gateway endpoint URL, ex. \"ws://localhost:3003/\""); + + if (hasErrors) { + console.error( + "[Config] Your config has invalid values. Fix them first https://docs.spacebar.chat/setup/server/configuration", + ); + console.error("[Config] Hint: if you're just testing with bundle (`npm run start`), you can set all endpoint URLs to [proto]://localhost:3001"); + process.exit(1); + } else console.log("[Config] Configuration validated successfully."); +} \ No newline at end of file