onbuzz 4.6.4 → 4.7.1
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/bin/cli.js +8 -0
- package/package.json +1 -1
- package/scripts/debug-balance-probe.mjs +35 -0
- package/src/__tests__/autoUpdateConfig.test.js +80 -0
- package/src/__tests__/releaseWorkflow.test.js +72 -0
- package/src/core/__tests__/messageProcessor.sourceHeader.test.js +7 -2
- package/src/index.js +16 -0
- package/src/interfaces/__tests__/accountRoutes.test.js +487 -0
- package/src/interfaces/__tests__/apiKeyManagerContract.test.js +39 -0
- package/src/interfaces/__tests__/authRoutes.test.js +8 -8
- package/src/interfaces/accountRoutes.js +398 -0
- package/src/interfaces/webServer.js +104 -15
- package/src/services/__tests__/apiKeyManager.test.js +4 -6
- package/src/services/__tests__/authCacheStore.test.js +118 -0
- package/src/services/__tests__/channelRelay.integration.test.js +49 -12
- package/src/services/__tests__/messageSource.test.js +6 -2
- package/src/services/__tests__/telegramBlockParser.test.js +183 -0
- package/src/services/__tests__/telegramService.test.js +838 -0
- package/src/services/apiKeyManager.js +12 -99
- package/src/services/authCacheStore.js +140 -0
- package/src/services/messageSource.js +11 -11
- package/src/services/telegramBlockParser.js +145 -0
- package/src/services/telegramService.js +1273 -431
- package/src/tools/__tests__/webTool.e2e.test.js +9 -1
- package/src/tools/webTool.js +20 -4
- package/src/utilities/__tests__/secretsCipher.test.js +97 -0
- package/src/utilities/__tests__/updateNotifier.test.js +139 -0
- package/src/utilities/secretsCipher.js +116 -0
- package/src/utilities/updateNotifier.js +140 -0
- package/web-ui/build/index.html +2 -2
- package/web-ui/build/static/1c-CuE_dLW8.js +1 -0
- package/web-ui/build/static/abap-LOu14tBm.js +1 -0
- package/web-ui/build/static/abnf-CJpfHQLV.js +1 -0
- package/web-ui/build/static/abnf-LdAi7OAY.js +1 -0
- package/web-ui/build/static/accesslog-BvrhdZIJ.js +1 -0
- package/web-ui/build/static/actionscript-B3NHp9II.js +1 -0
- package/web-ui/build/static/actionscript-DVfqv5DS.js +1 -0
- package/web-ui/build/static/ada-BVkvHgSu.js +1 -0
- package/web-ui/build/static/ada-d33rlRPC.js +1 -0
- package/web-ui/build/static/agda-t1mot-jT.js +1 -0
- package/web-ui/build/static/al-D2Aw8sYi.js +1 -0
- package/web-ui/build/static/angelscript-DGjq6ZLh.js +1 -0
- package/web-ui/build/static/antlr4-DQWExQhj.js +1 -0
- package/web-ui/build/static/apache-CRX2mGHA.js +1 -0
- package/web-ui/build/static/apacheconf-BBhhyVVR.js +1 -0
- package/web-ui/build/static/apex-DIJyAF3g.js +1 -0
- package/web-ui/build/static/apl-COGQUhmX.js +1 -0
- package/web-ui/build/static/applescript-DLPa_bvL.js +1 -0
- package/web-ui/build/static/applescript-iEepawXM.js +1 -0
- package/web-ui/build/static/aql-vDYotUbW.js +1 -0
- package/web-ui/build/static/arcade-5bpnh2Oi.js +1 -0
- package/web-ui/build/static/arduino-4OxI8HS8.js +1 -0
- package/web-ui/build/static/arduino-zJUNF7Xl.js +1 -0
- package/web-ui/build/static/arff-DHcdYO6-.js +1 -0
- package/web-ui/build/static/armasm-DVyTHmiD.js +1 -0
- package/web-ui/build/static/asciidoc-BRYIR6BF.js +1 -0
- package/web-ui/build/static/asciidoc-bd_scw1t.js +1 -0
- package/web-ui/build/static/asm6502-DfRcm1MU.js +1 -0
- package/web-ui/build/static/asmatmel--fvKJXxu.js +1 -0
- package/web-ui/build/static/aspectj-Cnm2Ccyg.js +1 -0
- package/web-ui/build/static/aspnet-BK2pQltF.js +1 -0
- package/web-ui/build/static/autohotkey-COkKlASn.js +1 -0
- package/web-ui/build/static/autohotkey-DNYipPv0.js +1 -0
- package/web-ui/build/static/autoit-DiwhqkEo.js +1 -0
- package/web-ui/build/static/autoit-DkQ_YDdk.js +1 -0
- package/web-ui/build/static/avisynth-DFrkQWrl.js +1 -0
- package/web-ui/build/static/avrasm-BbFtsKVm.js +1 -0
- package/web-ui/build/static/avro-idl-06_wFrxE.js +1 -0
- package/web-ui/build/static/awk-BNO1Hu3Y.js +1 -0
- package/web-ui/build/static/axapta-CW0rBEQf.js +1 -0
- package/web-ui/build/static/bash-DAP5H41u.js +1 -0
- package/web-ui/build/static/bash-DsCT4fHh.js +1 -0
- package/web-ui/build/static/basic-DqCcX17x.js +1 -0
- package/web-ui/build/static/basic-J3jqGQaz.js +1 -0
- package/web-ui/build/static/batch-BzKb0QuF.js +1 -0
- package/web-ui/build/static/bbcode-Cxys0qL9.js +1 -0
- package/web-ui/build/static/bicep-DPpVhf9I.js +1 -0
- package/web-ui/build/static/birb-BDF00uY2.js +1 -0
- package/web-ui/build/static/bison-DerSCeTc.js +1 -0
- package/web-ui/build/static/bnf--Nxb91Mj.js +1 -0
- package/web-ui/build/static/bnf-DKp1OqQh.js +1 -0
- package/web-ui/build/static/brainfuck-BgKburBi.js +1 -0
- package/web-ui/build/static/brainfuck-CLRabJhl.js +1 -0
- package/web-ui/build/static/brightscript-DJ0LrgUU.js +1 -0
- package/web-ui/build/static/bro-FVn3137a.js +1 -0
- package/web-ui/build/static/bsl-DGcfC5Qq.js +1 -0
- package/web-ui/build/static/c-CtBaJxj_.js +1 -0
- package/web-ui/build/static/c-DcJBPsOs.js +1 -0
- package/web-ui/build/static/c-like-BMAPMOT0.js +1 -0
- package/web-ui/build/static/cal-Dwvf5LQJ.js +1 -0
- package/web-ui/build/static/capnproto-Be5xeQu8.js +1 -0
- package/web-ui/build/static/ceylon-BV9kQegc.js +1 -0
- package/web-ui/build/static/cfscript-DqyqkqRV.js +1 -0
- package/web-ui/build/static/chaiscript-ab8S5sGz.js +1 -0
- package/web-ui/build/static/cil-DU5bEU16.js +1 -0
- package/web-ui/build/static/clean-CqKiC4l-.js +1 -0
- package/web-ui/build/static/clojure-CdaWManm.js +1 -0
- package/web-ui/build/static/clojure-cVIUydqy.js +1 -0
- package/web-ui/build/static/clojure-repl-mc7sqsOd.js +1 -0
- package/web-ui/build/static/cmake-D2ntzyPv.js +1 -0
- package/web-ui/build/static/cmake-Dt7gdCZl.js +1 -0
- package/web-ui/build/static/cobol-BYMIYxJY.js +1 -0
- package/web-ui/build/static/coffeescript-COUOYE5O.js +1 -0
- package/web-ui/build/static/coffeescript-FDyQzH4X.js +1 -0
- package/web-ui/build/static/concurnas-D8GglsJx.js +1 -0
- package/web-ui/build/static/coq-BvEL_B0N.js +1 -0
- package/web-ui/build/static/coq-C6NZeAuz.js +1 -0
- package/web-ui/build/static/cos-CjjeNVfD.js +1 -0
- package/web-ui/build/static/cpp-BdQQ9k01.js +1 -0
- package/web-ui/build/static/cpp-iYGopslr.js +1 -0
- package/web-ui/build/static/crmsh-COhOWlQB.js +1 -0
- package/web-ui/build/static/crystal-DqVfuZe7.js +1 -0
- package/web-ui/build/static/crystal-fkI7WHLA.js +1 -0
- package/web-ui/build/static/csharp-BKyMR69a.js +1 -0
- package/web-ui/build/static/csharp-KJwk5tFh.js +1 -0
- package/web-ui/build/static/cshtml-D-0Bd5yF.js +1 -0
- package/web-ui/build/static/csp-C6xrFQUZ.js +1 -0
- package/web-ui/build/static/csp-CKOZZjS5.js +1 -0
- package/web-ui/build/static/css-DhttYfIQ.js +1 -0
- package/web-ui/build/static/css-extras-Cwksdn14.js +1 -0
- package/web-ui/build/static/csv-3xOycrIm.js +1 -0
- package/web-ui/build/static/cypher-DIQ_IXvU.js +1 -0
- package/web-ui/build/static/d-CA3ONaPZ.js +1 -0
- package/web-ui/build/static/d-Cpj6yr1P.js +1 -0
- package/web-ui/build/static/dart-CStXueOh.js +1 -0
- package/web-ui/build/static/dart-DyyN2hCZ.js +1 -0
- package/web-ui/build/static/dataweave-C1Z1lf_p.js +1 -0
- package/web-ui/build/static/dax-Bra_xxin.js +1 -0
- package/web-ui/build/static/delphi-BSp32sTR.js +1 -0
- package/web-ui/build/static/dhall-DqULvWhD.js +1 -0
- package/web-ui/build/static/diff-DZWp0eai.js +1 -0
- package/web-ui/build/static/diff-Dl7Q9ZLJ.js +1 -0
- package/web-ui/build/static/django-BKb-9srn.js +1 -0
- package/web-ui/build/static/django-D4ZBsr7A.js +1 -0
- package/web-ui/build/static/dns-BIl1lqfE.js +1 -0
- package/web-ui/build/static/dns-zone-file-BHOpqtwv.js +1 -0
- package/web-ui/build/static/docker-DhYlo5KM.js +1 -0
- package/web-ui/build/static/dockerfile-DkKcxplU.js +1 -0
- package/web-ui/build/static/dos-BL8RAxlP.js +1 -0
- package/web-ui/build/static/dot-BLokvOTb.js +1 -0
- package/web-ui/build/static/dsconfig-C-HwSveF.js +1 -0
- package/web-ui/build/static/dts-D7N7kY9U.js +1 -0
- package/web-ui/build/static/dust-BDDbpTgO.js +1 -0
- package/web-ui/build/static/ebnf-BXq1reNT.js +1 -0
- package/web-ui/build/static/ebnf-DbPDw4Bq.js +1 -0
- package/web-ui/build/static/editorconfig-w2ZfPGuw.js +1 -0
- package/web-ui/build/static/eiffel-c2MQNBkW.js +1 -0
- package/web-ui/build/static/ejs-3QktTSvM.js +1 -0
- package/web-ui/build/static/elixir-BpckBbUo.js +1 -0
- package/web-ui/build/static/elixir-CdGx--Zx.js +1 -0
- package/web-ui/build/static/elm-BZQYORvs.js +1 -0
- package/web-ui/build/static/elm-CuB52FFf.js +1 -0
- package/web-ui/build/static/erb-BBShdpRp.js +1 -0
- package/web-ui/build/static/erb-C6oyD8uR.js +1 -0
- package/web-ui/build/static/erlang-CTR2NiVN.js +1 -0
- package/web-ui/build/static/erlang-Gyvyd8Bt.js +1 -0
- package/web-ui/build/static/erlang-repl-DQ9M2hTB.js +1 -0
- package/web-ui/build/static/etlua-WvCpEBL7.js +1 -0
- package/web-ui/build/static/excel-Cti8qyDh.js +1 -0
- package/web-ui/build/static/excel-formula-CbyjGhLT.js +1 -0
- package/web-ui/build/static/factor-DsS7xUlQ.js +1 -0
- package/web-ui/build/static/false-By7DT7NY.js +1 -0
- package/web-ui/build/static/firestore-security-rules-D818j5mX.js +1 -0
- package/web-ui/build/static/fix-Z9CNHO5B.js +1 -0
- package/web-ui/build/static/flix-CQ5tU7oG.js +1 -0
- package/web-ui/build/static/flow-TAcj5V8G.js +1 -0
- package/web-ui/build/static/fortran-CSo4-IB9.js +1 -0
- package/web-ui/build/static/fortran-D8ckpcuk.js +1 -0
- package/web-ui/build/static/fsharp-CX5IhzHG.js +1 -0
- package/web-ui/build/static/fsharp-CjgdWVzI.js +1 -0
- package/web-ui/build/static/ftl-BniZfpaP.js +1 -0
- package/web-ui/build/static/gams-Dx_Ej7b0.js +1 -0
- package/web-ui/build/static/gap-BW8rQPKU.js +1 -0
- package/web-ui/build/static/gauss-DP_j2AoM.js +1 -0
- package/web-ui/build/static/gcode-C_p0RHK2.js +1 -0
- package/web-ui/build/static/gcode-CvPzqlIr.js +1 -0
- package/web-ui/build/static/gdscript-BQxanI3X.js +1 -0
- package/web-ui/build/static/gedcom-DX22sB95.js +1 -0
- package/web-ui/build/static/gherkin-BuM2TN92.js +1 -0
- package/web-ui/build/static/gherkin-SyKtGAnl.js +1 -0
- package/web-ui/build/static/git-CZsBJbLj.js +1 -0
- package/web-ui/build/static/glsl-0gMMTGpT.js +1 -0
- package/web-ui/build/static/glsl-DdxyDP7O.js +1 -0
- package/web-ui/build/static/gml-Bmf5f_3a.js +1 -0
- package/web-ui/build/static/gml-DygwvUqd.js +1 -0
- package/web-ui/build/static/gn-CmJ9lVHR.js +1 -0
- package/web-ui/build/static/go-DcXIw3ql.js +1 -0
- package/web-ui/build/static/go-Dp-1fwju.js +1 -0
- package/web-ui/build/static/go-module-CVe5dTg-.js +1 -0
- package/web-ui/build/static/golo-Dqz3BdPW.js +1 -0
- package/web-ui/build/static/gradle-PY8Q_ptd.js +1 -0
- package/web-ui/build/static/graphql-7ynBfuuQ.js +1 -0
- package/web-ui/build/static/groovy-CKe3t1A3.js +1 -0
- package/web-ui/build/static/groovy-DK_6c_Dy.js +1 -0
- package/web-ui/build/static/haml-BjjIreuG.js +1 -0
- package/web-ui/build/static/haml-knbHtzU7.js +1 -0
- package/web-ui/build/static/handlebars-Bvicc2ZP.js +1 -0
- package/web-ui/build/static/handlebars-CWjisUes.js +1 -0
- package/web-ui/build/static/haskell-0vOFJmtj.js +1 -0
- package/web-ui/build/static/haskell-BjwWvVul.js +1 -0
- package/web-ui/build/static/haxe-CXIYhI9-.js +1 -0
- package/web-ui/build/static/haxe-Msa_nat5.js +1 -0
- package/web-ui/build/static/hcl-DADfqiqO.js +1 -0
- package/web-ui/build/static/hlsl-BoecwvZ1.js +1 -0
- package/web-ui/build/static/hoon-DoMcF4bN.js +1 -0
- package/web-ui/build/static/hpkp-DOkWWV9B.js +1 -0
- package/web-ui/build/static/hsp-KvanktXQ.js +1 -0
- package/web-ui/build/static/hsts-DP5sAe8p.js +1 -0
- package/web-ui/build/static/htmlbars-DpevdeqY.js +1 -0
- package/web-ui/build/static/http-CTyudxeK.js +1 -0
- package/web-ui/build/static/http-D0_pALtR.js +1 -0
- package/web-ui/build/static/hy-KpsNGTaA.js +1 -0
- package/web-ui/build/static/ichigojam-B9szb3eY.js +1 -0
- package/web-ui/build/static/icon-nqAgdt4t.js +1 -0
- package/web-ui/build/static/icu-message-format-DvgC-cKZ.js +1 -0
- package/web-ui/build/static/idris-D5VcDmFg.js +1 -0
- package/web-ui/build/static/iecst-LbbDhK7w.js +1 -0
- package/web-ui/build/static/ignore-rThoz4zA.js +1 -0
- package/web-ui/build/static/index-Cm1gK3R7.css +1 -0
- package/web-ui/build/static/index-D6blIL5t.js +13 -0
- package/web-ui/build/static/index-DqCutaVi.js +1164 -0
- package/web-ui/build/static/index-_UVy_UGY.js +1 -0
- package/web-ui/build/static/inform7-B2u0-vkK.js +1 -0
- package/web-ui/build/static/inform7-Cj2uMx5P.js +1 -0
- package/web-ui/build/static/ini-DDC_WfpB.js +1 -0
- package/web-ui/build/static/ini-Dafi1wkS.js +1 -0
- package/web-ui/build/static/io-Cs5RmCdQ.js +1 -0
- package/web-ui/build/static/irpf90-5KuyCx_k.js +1 -0
- package/web-ui/build/static/isbl-CZGAUFN3.js +1 -0
- package/web-ui/build/static/j-C2U5CNx3.js +1 -0
- package/web-ui/build/static/java-B-L3bHbG.js +1 -0
- package/web-ui/build/static/java-Dhfb499l.js +1 -0
- package/web-ui/build/static/javadoc-_ln2gn5I.js +1 -0
- package/web-ui/build/static/javadoclike-CnV_ddKg.js +1 -0
- package/web-ui/build/static/javascript-DBUUUlif.js +1 -0
- package/web-ui/build/static/javastacktrace-BS1l3Yf6.js +1 -0
- package/web-ui/build/static/jboss-cli-RdKEfNzL.js +1 -0
- package/web-ui/build/static/jexl-Bu5vdWnx.js +1 -0
- package/web-ui/build/static/jolie-LS18mxou.js +1 -0
- package/web-ui/build/static/jq-u9QEjWr_.js +1 -0
- package/web-ui/build/static/js-extras-C1cS_85G.js +1 -0
- package/web-ui/build/static/js-templates-DQxgBfhh.js +1 -0
- package/web-ui/build/static/jsdoc-DhLXAtzJ.js +1 -0
- package/web-ui/build/static/json-B8DgcmbV.js +1 -0
- package/web-ui/build/static/json-ByLJzbD8.js +1 -0
- package/web-ui/build/static/json5-DSnccLNQ.js +1 -0
- package/web-ui/build/static/jsonp-CcwF40Vu.js +1 -0
- package/web-ui/build/static/jsstacktrace-7YvddNWa.js +1 -0
- package/web-ui/build/static/jsx-DnHkAc3-.js +1 -0
- package/web-ui/build/static/julia-BmadVpf3.js +1 -0
- package/web-ui/build/static/julia-GSKCoIBJ.js +1 -0
- package/web-ui/build/static/julia-repl-ks3HTctE.js +1 -0
- package/web-ui/build/static/keepalived-CWDkM2-Z.js +1 -0
- package/web-ui/build/static/keyman-C9jA4-3Y.js +1 -0
- package/web-ui/build/static/kotlin-BqzUXT-K.js +1 -0
- package/web-ui/build/static/kotlin-BxhEUQAU.js +1 -0
- package/web-ui/build/static/kumir-BFYLWJq-.js +1 -0
- package/web-ui/build/static/kusto-CQRzYXm2.js +1 -0
- package/web-ui/build/static/lasso-D44z_uI8.js +1 -0
- package/web-ui/build/static/latex-BEJdTqYC.js +1 -0
- package/web-ui/build/static/latex-CStS4ql1.js +1 -0
- package/web-ui/build/static/latte-BPXasl8T.js +1 -0
- package/web-ui/build/static/ldif-Wxrk2-xQ.js +1 -0
- package/web-ui/build/static/leaf-DrTXK-pT.js +1 -0
- package/web-ui/build/static/less-BmoAe98U.js +1 -0
- package/web-ui/build/static/less-DzWEFsZj.js +1 -0
- package/web-ui/build/static/lilypond-C3ZnRm_L.js +1 -0
- package/web-ui/build/static/liquid-eXmypvP_.js +1 -0
- package/web-ui/build/static/lisp-DcidyoAl.js +1 -0
- package/web-ui/build/static/lisp-DhmUig93.js +1 -0
- package/web-ui/build/static/livecodeserver-D5lnfCkg.js +1 -0
- package/web-ui/build/static/livescript-Bpb_EpXS.js +1 -0
- package/web-ui/build/static/livescript-rF5whmjG.js +1 -0
- package/web-ui/build/static/llvm-BD9QG7T-.js +1 -0
- package/web-ui/build/static/llvm-CVP-jOx8.js +1 -0
- package/web-ui/build/static/log-DRzysjS2.js +1 -0
- package/web-ui/build/static/lolcode-BmKgPOwi.js +1 -0
- package/web-ui/build/static/lsl-DEO2mV0F.js +1 -0
- package/web-ui/build/static/lua-BNDDIa9F.js +1 -0
- package/web-ui/build/static/lua-C5n4hyV-.js +1 -0
- package/web-ui/build/static/magma-UZvvdXue.js +1 -0
- package/web-ui/build/static/makefile-BDQ4tARf.js +1 -0
- package/web-ui/build/static/makefile-Bjg-ueA2.js +1 -0
- package/web-ui/build/static/markdown-BTXvpQos.js +1 -0
- package/web-ui/build/static/markdown-BvMdFo1Y.js +1 -0
- package/web-ui/build/static/markup-templating-xSAHnnIS.js +1 -0
- package/web-ui/build/static/mathematica-CqNsUy6n.js +1 -0
- package/web-ui/build/static/matlab-D-A1WMHc.js +1 -0
- package/web-ui/build/static/matlab-Us_SxUWG.js +1 -0
- package/web-ui/build/static/maxima-BSyBp09v.js +1 -0
- package/web-ui/build/static/maxscript-wyb-3dgT.js +1 -0
- package/web-ui/build/static/mel-Bpo7JK_A.js +1 -0
- package/web-ui/build/static/mel-eZCDX4iS.js +1 -0
- package/web-ui/build/static/mercury-CEgBiaXI.js +1 -0
- package/web-ui/build/static/mermaid-BJIHmQsO.js +1 -0
- package/web-ui/build/static/mipsasm-c70dMcw9.js +1 -0
- package/web-ui/build/static/mizar-CeCpdHS-.js +1 -0
- package/web-ui/build/static/mizar-DDlOFZXr.js +1 -0
- package/web-ui/build/static/mojolicious-b4UGVld0.js +1 -0
- package/web-ui/build/static/mongodb-DwkU2uSm.js +1 -0
- package/web-ui/build/static/monkey-CNkGqOfo.js +1 -0
- package/web-ui/build/static/monkey-DwmdAwUx.js +1 -0
- package/web-ui/build/static/moonscript-C2vv4alq.js +1 -0
- package/web-ui/build/static/moonscript-GOmGojxm.js +1 -0
- package/web-ui/build/static/n1ql-B-uZXYG_.js +1 -0
- package/web-ui/build/static/n1ql-CqKgc7lF.js +1 -0
- package/web-ui/build/static/n4js-CLkxsn24.js +1 -0
- package/web-ui/build/static/nand2tetris-hdl-CAJAzliK.js +1 -0
- package/web-ui/build/static/naniscript-DxWjsrnl.js +1 -0
- package/web-ui/build/static/nasm-C-GI38un.js +1 -0
- package/web-ui/build/static/neon-DWKBFo--.js +1 -0
- package/web-ui/build/static/nevod-DGDg1w8a.js +1 -0
- package/web-ui/build/static/nginx-BQbAompS.js +1 -0
- package/web-ui/build/static/nginx-BQbgG8J2.js +1 -0
- package/web-ui/build/static/nim-Bf864jik.js +1 -0
- package/web-ui/build/static/nim-DG4Tf5sg.js +1 -0
- package/web-ui/build/static/nix-BBq54ypW.js +1 -0
- package/web-ui/build/static/nix-DiVQTSyM.js +1 -0
- package/web-ui/build/static/node-repl-Dg0rNxhv.js +1 -0
- package/web-ui/build/static/nsis-BG8Lm28v.js +1 -0
- package/web-ui/build/static/nsis-CwA_MNyF.js +1 -0
- package/web-ui/build/static/objectivec-83FM4mu0.js +1 -0
- package/web-ui/build/static/objectivec-CbDgPZGc.js +1 -0
- package/web-ui/build/static/ocaml-CXrksX9b.js +1 -0
- package/web-ui/build/static/ocaml-aktipfk_.js +1 -0
- package/web-ui/build/static/opencl-B1Wu4nP5.js +1 -0
- package/web-ui/build/static/openqasm-BnUjC0Rq.js +1 -0
- package/web-ui/build/static/openscad-CNEF75nQ.js +1 -0
- package/web-ui/build/static/oxygene-B5nQHVvu.js +1 -0
- package/web-ui/build/static/oz-Dw07HFRJ.js +1 -0
- package/web-ui/build/static/parigp-Dkh7PqN8.js +1 -0
- package/web-ui/build/static/parser-CAW1btwt.js +1 -0
- package/web-ui/build/static/parser3-DO4cmbnD.js +1 -0
- package/web-ui/build/static/pascal-B3XwEzrN.js +1 -0
- package/web-ui/build/static/pascaligo-CMKmAZ_B.js +1 -0
- package/web-ui/build/static/pcaxis-B5RrdB6p.js +1 -0
- package/web-ui/build/static/peoplecode-CGkgPJl9.js +1 -0
- package/web-ui/build/static/perl-BWBuZ5Vt.js +1 -0
- package/web-ui/build/static/perl-CW0_w5xG.js +1 -0
- package/web-ui/build/static/pf-B1aiG4iq.js +1 -0
- package/web-ui/build/static/pgsql-BgXadqYx.js +1 -0
- package/web-ui/build/static/php-BpB9heTH.js +1 -0
- package/web-ui/build/static/php-S3LJn70M.js +1 -0
- package/web-ui/build/static/php-extras-Dmblzt0I.js +1 -0
- package/web-ui/build/static/php-template-BS_uyUS1.js +1 -0
- package/web-ui/build/static/phpdoc-BqP_4LKt.js +1 -0
- package/web-ui/build/static/plaintext-BvDBRLjE.js +1 -0
- package/web-ui/build/static/plsql-DEj_qOIm.js +1 -0
- package/web-ui/build/static/pony-DpvrOLZf.js +1 -0
- package/web-ui/build/static/powerquery-C0Wobunx.js +1 -0
- package/web-ui/build/static/powershell-CY7ZBlTW.js +1 -0
- package/web-ui/build/static/powershell-DiEDDrOo.js +1 -0
- package/web-ui/build/static/processing-IXybgMWQ.js +1 -0
- package/web-ui/build/static/processing-i136WolF.js +1 -0
- package/web-ui/build/static/profile-guIih27Q.js +1 -0
- package/web-ui/build/static/prolog-CvmO0VDt.js +1 -0
- package/web-ui/build/static/prolog-Dmf4klwf.js +1 -0
- package/web-ui/build/static/promql-DObZhyF5.js +1 -0
- package/web-ui/build/static/properties-CK08qg7k.js +1 -0
- package/web-ui/build/static/properties-DmwePx7J.js +1 -0
- package/web-ui/build/static/protobuf-BDkUYcAx.js +1 -0
- package/web-ui/build/static/protobuf-CBMNyvhU.js +1 -0
- package/web-ui/build/static/psl-eW3BB0n6.js +1 -0
- package/web-ui/build/static/pug-D0LF-keh.js +1 -0
- package/web-ui/build/static/puppet-BUYZQfB-.js +1 -0
- package/web-ui/build/static/puppet-Dbo5UDT-.js +1 -0
- package/web-ui/build/static/pure-C5ukDHhg.js +1 -0
- package/web-ui/build/static/purebasic-B8eqrPTw.js +1 -0
- package/web-ui/build/static/purebasic-BA8g0-l-.js +1 -0
- package/web-ui/build/static/purescript-CKa_o5qx.js +1 -0
- package/web-ui/build/static/python-C-iEDsum.js +1 -0
- package/web-ui/build/static/python-CJcHyEGQ.js +1 -0
- package/web-ui/build/static/python-repl-WvDxhQ8t.js +1 -0
- package/web-ui/build/static/q-Ben5hioy.js +1 -0
- package/web-ui/build/static/q-CenUx0Za.js +1 -0
- package/web-ui/build/static/qml-CkUJB-7R.js +1 -0
- package/web-ui/build/static/qml-G6uEqbt_.js +1 -0
- package/web-ui/build/static/qore-CASrYvaT.js +1 -0
- package/web-ui/build/static/qsharp-CJMvScJV.js +1 -0
- package/web-ui/build/static/r-C3qOLTEa.js +1 -0
- package/web-ui/build/static/r-pFTIkWVX.js +1 -0
- package/web-ui/build/static/racket-Dj2Pnxz8.js +1 -0
- package/web-ui/build/static/reason-BLo81vJj.js +1 -0
- package/web-ui/build/static/reasonml-Uso3eiRd.js +1 -0
- package/web-ui/build/static/regex-CRRrWtDv.js +1 -0
- package/web-ui/build/static/rego-Pd9N41dQ.js +1 -0
- package/web-ui/build/static/renpy-B5nJRJ6W.js +1 -0
- package/web-ui/build/static/rest-C4KktBYV.js +1 -0
- package/web-ui/build/static/rib-WhwJFXjw.js +1 -0
- package/web-ui/build/static/rip-BRMu9y5Q.js +1 -0
- package/web-ui/build/static/roboconf-BC-HzyUK.js +1 -0
- package/web-ui/build/static/roboconf-Wo-TPzlW.js +1 -0
- package/web-ui/build/static/robotframework-Cvw8u8mL.js +1 -0
- package/web-ui/build/static/routeros-1EUCLy_j.js +1 -0
- package/web-ui/build/static/rsl-DcVNeKkF.js +1 -0
- package/web-ui/build/static/ruby-B1fqRC3j.js +1 -0
- package/web-ui/build/static/ruby-Bl1wXNzL.js +1 -0
- package/web-ui/build/static/ruleslanguage-C3rzl2Ma.js +1 -0
- package/web-ui/build/static/rust-4iyLrpFQ.js +1 -0
- package/web-ui/build/static/rust-V8MRv3os.js +1 -0
- package/web-ui/build/static/sas-ClkrCklD.js +1 -0
- package/web-ui/build/static/sas-CyFFy3mS.js +1 -0
- package/web-ui/build/static/sass-Cege3fu1.js +1 -0
- package/web-ui/build/static/scala-DNb7CDvN.js +1 -0
- package/web-ui/build/static/scala-c5k_CS9h.js +1 -0
- package/web-ui/build/static/scheme-BXrEBzXP.js +1 -0
- package/web-ui/build/static/scheme-COq0pstl.js +1 -0
- package/web-ui/build/static/scilab-CRMCfvft.js +1 -0
- package/web-ui/build/static/scss-C6MDSdKd.js +1 -0
- package/web-ui/build/static/scss-D1INSi-r.js +1 -0
- package/web-ui/build/static/shell-BHTFz9Xv.js +1 -0
- package/web-ui/build/static/shell-session-B6KXgRjz.js +1 -0
- package/web-ui/build/static/smali-CXGHC3zj.js +1 -0
- package/web-ui/build/static/smali-DFRkIqFc.js +1 -0
- package/web-ui/build/static/smalltalk-DWI2TbuJ.js +1 -0
- package/web-ui/build/static/smalltalk-jkgxBKRZ.js +1 -0
- package/web-ui/build/static/smarty-BPJMXwnj.js +1 -0
- package/web-ui/build/static/sml-BHT8CCeD.js +1 -0
- package/web-ui/build/static/sml-D5fkPJU1.js +1 -0
- package/web-ui/build/static/solidity-BfFvCWqp.js +1 -0
- package/web-ui/build/static/solution-file-DmSVfk_X.js +1 -0
- package/web-ui/build/static/soy-CXqMJVf8.js +1 -0
- package/web-ui/build/static/sparql-BxIpMyhJ.js +1 -0
- package/web-ui/build/static/splunk-spl-DMekyRuD.js +1 -0
- package/web-ui/build/static/sqf-DeQ-Lyaa.js +1 -0
- package/web-ui/build/static/sqf-hkl5BOBV.js +1 -0
- package/web-ui/build/static/sql-Di-rn3Od.js +1 -0
- package/web-ui/build/static/sql-DuF5aX9R.js +1 -0
- package/web-ui/build/static/sql_more-CCmzwYYA.js +1 -0
- package/web-ui/build/static/squirrel-fGLPlBkB.js +1 -0
- package/web-ui/build/static/stan-BveEpl1w.js +1 -0
- package/web-ui/build/static/stan-CM09XtOD.js +1 -0
- package/web-ui/build/static/stata-DeFUbv91.js +1 -0
- package/web-ui/build/static/step21-DnUE2ZTl.js +1 -0
- package/web-ui/build/static/stylus-Bz9XG6KK.js +1 -0
- package/web-ui/build/static/stylus-h33ZUR4b.js +1 -0
- package/web-ui/build/static/subunit-v4SRMSnP.js +1 -0
- package/web-ui/build/static/swift-BMCxsbHv.js +1 -0
- package/web-ui/build/static/swift-qFBaTSsZ.js +1 -0
- package/web-ui/build/static/systemd-9w7KWsst.js +1 -0
- package/web-ui/build/static/t4-cs-DdBrJkO9.js +1 -0
- package/web-ui/build/static/t4-templating-B-3iQJ4y.js +1 -0
- package/web-ui/build/static/t4-vb-BBuTbPK8.js +1 -0
- package/web-ui/build/static/taggerscript-BPvYYpaJ.js +1 -0
- package/web-ui/build/static/tap-DiFULuZV.js +1 -0
- package/web-ui/build/static/tap-Q9DMgrzh.js +1 -0
- package/web-ui/build/static/tcl-BZcwcRUU.js +1 -0
- package/web-ui/build/static/tcl-C4DHKxjE.js +1 -0
- package/web-ui/build/static/textile-ByLAjlo8.js +1 -0
- package/web-ui/build/static/thrift-C_isEMNl.js +1 -0
- package/web-ui/build/static/toml-C6ffwJpv.js +1 -0
- package/web-ui/build/static/tp-aV8nCrpp.js +1 -0
- package/web-ui/build/static/tremor-Bs1SSWo9.js +1 -0
- package/web-ui/build/static/tsx-DdryYBa4.js +1 -0
- package/web-ui/build/static/tt2-BeCMXvbZ.js +1 -0
- package/web-ui/build/static/turtle-B2FzT5Ov.js +1 -0
- package/web-ui/build/static/twig-fVEYqAxR.js +1 -0
- package/web-ui/build/static/twig-p9k58-hx.js +1 -0
- package/web-ui/build/static/typescript-8bhStN7p.js +1 -0
- package/web-ui/build/static/typescript-D2zmnuDR.js +1 -0
- package/web-ui/build/static/typoscript-DQePQcKL.js +1 -0
- package/web-ui/build/static/unrealscript-BZYSnJjB.js +1 -0
- package/web-ui/build/static/uorazor-CGaRtqR5.js +1 -0
- package/web-ui/build/static/uri-PJ3dz1qj.js +1 -0
- package/web-ui/build/static/v-CI9qDsYZ.js +1 -0
- package/web-ui/build/static/vala-B4ses542.js +1 -0
- package/web-ui/build/static/vala-BLxHpeKp.js +1 -0
- package/web-ui/build/static/vbnet-B7Dzk1rR.js +1 -0
- package/web-ui/build/static/vbnet-HOI9SMLZ.js +1 -0
- package/web-ui/build/static/vbscript-ERv5iDpi.js +1 -0
- package/web-ui/build/static/vbscript-html-D-mjpNAX.js +1 -0
- package/web-ui/build/static/velocity-B754qmeE.js +1 -0
- package/web-ui/build/static/verilog-3PA83Bxs.js +1 -0
- package/web-ui/build/static/verilog-D-lqP5ci.js +1 -0
- package/web-ui/build/static/vhdl-BjRYdIRF.js +1 -0
- package/web-ui/build/static/vhdl-DgrorvTt.js +1 -0
- package/web-ui/build/static/vim-3Oixnlee.js +1 -0
- package/web-ui/build/static/vim-BJTKcXdU.js +1 -0
- package/web-ui/build/static/visual-basic-BG8-3339.js +1 -0
- package/web-ui/build/static/warpscript-CEIgv5UG.js +1 -0
- package/web-ui/build/static/wasm-BJlpp9rs.js +1 -0
- package/web-ui/build/static/web-idl-Dlh9DutO.js +1 -0
- package/web-ui/build/static/wiki-CCcmRzkd.js +1 -0
- package/web-ui/build/static/wolfram--Xk-fAUi.js +1 -0
- package/web-ui/build/static/wren-B9Ajd9OC.js +1 -0
- package/web-ui/build/static/x86asm-DJJ72Zy-.js +1 -0
- package/web-ui/build/static/xeora-C0tNsSDj.js +1 -0
- package/web-ui/build/static/xl-CzEpyjRJ.js +1 -0
- package/web-ui/build/static/xml-CdtQTsBH.js +1 -0
- package/web-ui/build/static/xml-doc-TtPAAmc6.js +1 -0
- package/web-ui/build/static/xojo-B92fAnQE.js +1 -0
- package/web-ui/build/static/xquery-D0Z1FZVO.js +1 -0
- package/web-ui/build/static/xquery-DwlcRJ7Q.js +1 -0
- package/web-ui/build/static/yaml-DySZjPvD.js +1 -0
- package/web-ui/build/static/yaml-YgOVzvAS.js +1 -0
- package/web-ui/build/static/yang-BJokKPTo.js +1 -0
- package/web-ui/build/static/zephir-BWMUFIRD.js +1 -0
- package/web-ui/build/static/zig-Bpzj48cM.js +1 -0
- package/web-ui/build/static/1c-4BRB87En.js +0 -1
- package/web-ui/build/static/abap-BXIqiAfL.js +0 -1
- package/web-ui/build/static/abnf-0gk1i0eD.js +0 -1
- package/web-ui/build/static/abnf-jcv7vN9a.js +0 -1
- package/web-ui/build/static/accesslog-bXE2aOZl.js +0 -1
- package/web-ui/build/static/actionscript-CF-bqawj.js +0 -1
- package/web-ui/build/static/actionscript-CodwLKar.js +0 -1
- package/web-ui/build/static/ada-BBEDI84F.js +0 -1
- package/web-ui/build/static/ada-Kb6JvaxP.js +0 -1
- package/web-ui/build/static/agda-UvnMXUUo.js +0 -1
- package/web-ui/build/static/al-D5QZ0ijQ.js +0 -1
- package/web-ui/build/static/angelscript-RpvZxbeT.js +0 -1
- package/web-ui/build/static/antlr4-BPyUvfii.js +0 -1
- package/web-ui/build/static/apache-CtM2pGik.js +0 -1
- package/web-ui/build/static/apacheconf-D-i9eISH.js +0 -1
- package/web-ui/build/static/apex-Dhn_SJi4.js +0 -1
- package/web-ui/build/static/apl-HWtdSaYy.js +0 -1
- package/web-ui/build/static/applescript-Br9NrmTP.js +0 -1
- package/web-ui/build/static/applescript-DLL0TuGw.js +0 -1
- package/web-ui/build/static/aql-MjCgNRUX.js +0 -1
- package/web-ui/build/static/arcade--DFvEPVv.js +0 -1
- package/web-ui/build/static/arduino-Cqw5W_fL.js +0 -1
- package/web-ui/build/static/arduino-DIDBbB7R.js +0 -1
- package/web-ui/build/static/arff-GGvbnOhc.js +0 -1
- package/web-ui/build/static/armasm-DKLRDLs1.js +0 -1
- package/web-ui/build/static/asciidoc-CN5qfm0K.js +0 -1
- package/web-ui/build/static/asciidoc-CeQEWYOj.js +0 -1
- package/web-ui/build/static/asm6502-B1l2Hc9j.js +0 -1
- package/web-ui/build/static/asmatmel-BAojNNWJ.js +0 -1
- package/web-ui/build/static/aspectj-DqZFhwdh.js +0 -1
- package/web-ui/build/static/aspnet-C0kQPqSr.js +0 -1
- package/web-ui/build/static/autohotkey-DY25td-Z.js +0 -1
- package/web-ui/build/static/autohotkey-DlqXINgk.js +0 -1
- package/web-ui/build/static/autoit-By7J2Y34.js +0 -1
- package/web-ui/build/static/autoit-nsu9sBga.js +0 -1
- package/web-ui/build/static/avisynth-DmhvVsr-.js +0 -1
- package/web-ui/build/static/avrasm-CHfBwwoQ.js +0 -1
- package/web-ui/build/static/avro-idl-BKgIWEIF.js +0 -1
- package/web-ui/build/static/awk-CpAb4d4E.js +0 -1
- package/web-ui/build/static/axapta-CM4aTfCZ.js +0 -1
- package/web-ui/build/static/bash-D1KTDlk-.js +0 -1
- package/web-ui/build/static/bash-DShkskxb.js +0 -1
- package/web-ui/build/static/basic-C4CfKvhg.js +0 -1
- package/web-ui/build/static/basic-CkQS4VwL.js +0 -1
- package/web-ui/build/static/batch-DZtrClI1.js +0 -1
- package/web-ui/build/static/bbcode-CY2FsfaO.js +0 -1
- package/web-ui/build/static/bicep-BeSEpm_3.js +0 -1
- package/web-ui/build/static/birb-huu22Mwu.js +0 -1
- package/web-ui/build/static/bison-CmbxfR57.js +0 -1
- package/web-ui/build/static/bnf-c2l_4HXN.js +0 -1
- package/web-ui/build/static/bnf-wucEDTqY.js +0 -1
- package/web-ui/build/static/brainfuck-CzWBg5U7.js +0 -1
- package/web-ui/build/static/brainfuck-I_YQ4sma.js +0 -1
- package/web-ui/build/static/brightscript-LOkD4eYW.js +0 -1
- package/web-ui/build/static/bro-CLJ7Afqo.js +0 -1
- package/web-ui/build/static/bsl-DbUgC2FQ.js +0 -1
- package/web-ui/build/static/c-C0S2D2ge.js +0 -1
- package/web-ui/build/static/c-KH25O_pL.js +0 -1
- package/web-ui/build/static/c-like-DtAFxyl_.js +0 -1
- package/web-ui/build/static/cal-uGiVJBNC.js +0 -1
- package/web-ui/build/static/capnproto-DSLchjOW.js +0 -1
- package/web-ui/build/static/ceylon-Bbxk66YL.js +0 -1
- package/web-ui/build/static/cfscript-CjDdgKbl.js +0 -1
- package/web-ui/build/static/chaiscript-CnRXaMae.js +0 -1
- package/web-ui/build/static/cil-CM9ygF3R.js +0 -1
- package/web-ui/build/static/clean-ppAH0SYy.js +0 -1
- package/web-ui/build/static/clojure-C5LVccGq.js +0 -1
- package/web-ui/build/static/clojure-DtLXiuuC.js +0 -1
- package/web-ui/build/static/clojure-repl-fSdrYuup.js +0 -1
- package/web-ui/build/static/cmake-AD1fuzSY.js +0 -1
- package/web-ui/build/static/cmake-D-o08Yta.js +0 -1
- package/web-ui/build/static/cobol-bDh1KHf9.js +0 -1
- package/web-ui/build/static/coffeescript-D8InK8kf.js +0 -1
- package/web-ui/build/static/coffeescript-MKWUOXb5.js +0 -1
- package/web-ui/build/static/concurnas-CR56nj6R.js +0 -1
- package/web-ui/build/static/coq-DDLBsBJu.js +0 -1
- package/web-ui/build/static/coq-WbhtANeW.js +0 -1
- package/web-ui/build/static/cos-Bfmre3op.js +0 -1
- package/web-ui/build/static/cpp-Cdy6A7gI.js +0 -1
- package/web-ui/build/static/cpp-De2KZejr.js +0 -1
- package/web-ui/build/static/crmsh-uf3vbKnN.js +0 -1
- package/web-ui/build/static/crystal-BHMyEVPP.js +0 -1
- package/web-ui/build/static/crystal-DXAQwftg.js +0 -1
- package/web-ui/build/static/csharp-Ci2MRG6L.js +0 -1
- package/web-ui/build/static/csharp-D8MV2a7f.js +0 -1
- package/web-ui/build/static/cshtml-kVj3v3uY.js +0 -1
- package/web-ui/build/static/csp-B83CCdVc.js +0 -1
- package/web-ui/build/static/csp-DUO7zlPh.js +0 -1
- package/web-ui/build/static/css-BWsx7mtO.js +0 -1
- package/web-ui/build/static/css-extras-oHch2Y5C.js +0 -1
- package/web-ui/build/static/csv-DIf0iNlc.js +0 -1
- package/web-ui/build/static/cypher-B1rOF_f3.js +0 -1
- package/web-ui/build/static/d-BUgLS87u.js +0 -1
- package/web-ui/build/static/d-ClM8XTCr.js +0 -1
- package/web-ui/build/static/dart-D5rVGtrb.js +0 -1
- package/web-ui/build/static/dart-Oal__k4m.js +0 -1
- package/web-ui/build/static/dataweave-B0uxnNDC.js +0 -1
- package/web-ui/build/static/dax-B9z6d1P6.js +0 -1
- package/web-ui/build/static/delphi-KMlx8q8A.js +0 -1
- package/web-ui/build/static/dhall-DLWFgSR8.js +0 -1
- package/web-ui/build/static/diff-DDMGnyhE.js +0 -1
- package/web-ui/build/static/diff-yg1oXq3U.js +0 -1
- package/web-ui/build/static/django-BDtkIu_c.js +0 -1
- package/web-ui/build/static/django-Bkn9HlyQ.js +0 -1
- package/web-ui/build/static/dns-Bx1VHfo6.js +0 -1
- package/web-ui/build/static/dns-zone-file-Bgn5zn_J.js +0 -1
- package/web-ui/build/static/docker-CTdrZJHc.js +0 -1
- package/web-ui/build/static/dockerfile-B7ziWbf_.js +0 -1
- package/web-ui/build/static/dos-cbBC5Icj.js +0 -1
- package/web-ui/build/static/dot-JXSVTLEH.js +0 -1
- package/web-ui/build/static/dsconfig-sEua2C2o.js +0 -1
- package/web-ui/build/static/dts-Zem_gT_O.js +0 -1
- package/web-ui/build/static/dust-B-dZ6-uQ.js +0 -1
- package/web-ui/build/static/ebnf-CXfeZoXF.js +0 -1
- package/web-ui/build/static/ebnf-raQs4FpT.js +0 -1
- package/web-ui/build/static/editorconfig-hp8ARbHf.js +0 -1
- package/web-ui/build/static/eiffel-tO3jaG00.js +0 -1
- package/web-ui/build/static/ejs-BGmD5Rvl.js +0 -1
- package/web-ui/build/static/elixir-CF0JDN9L.js +0 -1
- package/web-ui/build/static/elixir-CFSil_Ou.js +0 -1
- package/web-ui/build/static/elm-As6XaD-g.js +0 -1
- package/web-ui/build/static/elm-pw5GpqTZ.js +0 -1
- package/web-ui/build/static/erb-BrpCJIyN.js +0 -1
- package/web-ui/build/static/erb-D2_eJU9C.js +0 -1
- package/web-ui/build/static/erlang-5rSv6NMZ.js +0 -1
- package/web-ui/build/static/erlang-RCAxVMBd.js +0 -1
- package/web-ui/build/static/erlang-repl-BN0h_6XR.js +0 -1
- package/web-ui/build/static/etlua-BMtMnKtv.js +0 -1
- package/web-ui/build/static/excel-CRNS57iM.js +0 -1
- package/web-ui/build/static/excel-formula-BNw56R2m.js +0 -1
- package/web-ui/build/static/factor-7lsloWTf.js +0 -1
- package/web-ui/build/static/false-CQUvGnfd.js +0 -1
- package/web-ui/build/static/firestore-security-rules-WC1PabFS.js +0 -1
- package/web-ui/build/static/fix-Cs6kLeYV.js +0 -1
- package/web-ui/build/static/flix-1fdMgw2I.js +0 -1
- package/web-ui/build/static/flow-CRPduKSH.js +0 -1
- package/web-ui/build/static/fortran-C-3TUt5R.js +0 -1
- package/web-ui/build/static/fortran-CA4bbZCj.js +0 -1
- package/web-ui/build/static/fsharp-BScjCFae.js +0 -1
- package/web-ui/build/static/fsharp-BtHWuW4o.js +0 -1
- package/web-ui/build/static/ftl-Re-S2zvF.js +0 -1
- package/web-ui/build/static/gams-Cr12l-cM.js +0 -1
- package/web-ui/build/static/gap-H0O9-Zju.js +0 -1
- package/web-ui/build/static/gauss-CW8jwURx.js +0 -1
- package/web-ui/build/static/gcode-CIxfYtg9.js +0 -1
- package/web-ui/build/static/gcode-CVqRWYeB.js +0 -1
- package/web-ui/build/static/gdscript-BltZCaKl.js +0 -1
- package/web-ui/build/static/gedcom-nMT5ety_.js +0 -1
- package/web-ui/build/static/gherkin-B4M7CGOo.js +0 -1
- package/web-ui/build/static/gherkin-DumuqAQF.js +0 -1
- package/web-ui/build/static/git-BBiBlZ5H.js +0 -1
- package/web-ui/build/static/glsl-D8ckiRVo.js +0 -1
- package/web-ui/build/static/glsl-Z4VdDyPa.js +0 -1
- package/web-ui/build/static/gml-BHuSndHE.js +0 -1
- package/web-ui/build/static/gml-DZpfN_A4.js +0 -1
- package/web-ui/build/static/gn-BjpAHNh_.js +0 -1
- package/web-ui/build/static/go-BeZ9IgZB.js +0 -1
- package/web-ui/build/static/go-HEXrcgIc.js +0 -1
- package/web-ui/build/static/go-module-BGdPb7sP.js +0 -1
- package/web-ui/build/static/golo-Cr70KUbI.js +0 -1
- package/web-ui/build/static/gradle-C7MXrDnB.js +0 -1
- package/web-ui/build/static/graphql-CJK0wQjf.js +0 -1
- package/web-ui/build/static/groovy-Bwe7hkFG.js +0 -1
- package/web-ui/build/static/groovy-Dc6WDoKa.js +0 -1
- package/web-ui/build/static/haml-BSsAjltt.js +0 -1
- package/web-ui/build/static/haml-CZih7X_4.js +0 -1
- package/web-ui/build/static/handlebars-CN8hCpsy.js +0 -1
- package/web-ui/build/static/handlebars-XBLc7i13.js +0 -1
- package/web-ui/build/static/haskell-BH9WhK10.js +0 -1
- package/web-ui/build/static/haskell-Djf2J1vd.js +0 -1
- package/web-ui/build/static/haxe-BllD-W9e.js +0 -1
- package/web-ui/build/static/haxe-DY8Hyn7u.js +0 -1
- package/web-ui/build/static/hcl-CfktAP2o.js +0 -1
- package/web-ui/build/static/hlsl-B2JSOD9d.js +0 -1
- package/web-ui/build/static/hoon-BILyDobB.js +0 -1
- package/web-ui/build/static/hpkp-Bb8rXx4p.js +0 -1
- package/web-ui/build/static/hsp-BmjeJC21.js +0 -1
- package/web-ui/build/static/hsts-DJhW57Fu.js +0 -1
- package/web-ui/build/static/htmlbars-CJe_ZLjw.js +0 -1
- package/web-ui/build/static/http-D7SlABvQ.js +0 -1
- package/web-ui/build/static/http-DEUJqmEm.js +0 -1
- package/web-ui/build/static/hy-DVfsgEbr.js +0 -1
- package/web-ui/build/static/ichigojam-CPdz2bOt.js +0 -1
- package/web-ui/build/static/icon-DYK9RbU9.js +0 -1
- package/web-ui/build/static/icu-message-format-HiZB_alB.js +0 -1
- package/web-ui/build/static/idris-Clk3tJIE.js +0 -1
- package/web-ui/build/static/iecst-D7wkeksq.js +0 -1
- package/web-ui/build/static/ignore-GSm-L3jG.js +0 -1
- package/web-ui/build/static/index-BJe5td0v.js +0 -13
- package/web-ui/build/static/index-BYvljeMN.js +0 -1
- package/web-ui/build/static/index-CLelJq9j.js +0 -1156
- package/web-ui/build/static/index-f5UnFSsY.css +0 -1
- package/web-ui/build/static/inform7-D3gc0hSc.js +0 -1
- package/web-ui/build/static/inform7-DLdvZTxX.js +0 -1
- package/web-ui/build/static/ini-CVcWx1TA.js +0 -1
- package/web-ui/build/static/ini-CxYBdsvZ.js +0 -1
- package/web-ui/build/static/io-D760QF0i.js +0 -1
- package/web-ui/build/static/irpf90-DfkXdZut.js +0 -1
- package/web-ui/build/static/isbl-Bl3W-krY.js +0 -1
- package/web-ui/build/static/j-DyJj9FSc.js +0 -1
- package/web-ui/build/static/java-CLw1cH97.js +0 -1
- package/web-ui/build/static/java-vXaHBzP4.js +0 -1
- package/web-ui/build/static/javadoc-p5hIe48g.js +0 -1
- package/web-ui/build/static/javadoclike-OXi-sQ0q.js +0 -1
- package/web-ui/build/static/javascript-CTSqES8o.js +0 -1
- package/web-ui/build/static/javastacktrace-PC9-3moA.js +0 -1
- package/web-ui/build/static/jboss-cli-CxOZKDLi.js +0 -1
- package/web-ui/build/static/jexl-C4kSXhD1.js +0 -1
- package/web-ui/build/static/jolie-CntM8cWx.js +0 -1
- package/web-ui/build/static/jq-D_4bTCm0.js +0 -1
- package/web-ui/build/static/js-extras-Cx9VAZJd.js +0 -1
- package/web-ui/build/static/js-templates-BqyJUDxJ.js +0 -1
- package/web-ui/build/static/jsdoc-CNHLgAph.js +0 -1
- package/web-ui/build/static/json-BXIFrbVC.js +0 -1
- package/web-ui/build/static/json-DRUrJL_F.js +0 -1
- package/web-ui/build/static/json5-EsTrOpXr.js +0 -1
- package/web-ui/build/static/jsonp-RijEuTJY.js +0 -1
- package/web-ui/build/static/jsstacktrace-dM13uE1y.js +0 -1
- package/web-ui/build/static/jsx-Cf0j02DZ.js +0 -1
- package/web-ui/build/static/julia-BLrtj5Dj.js +0 -1
- package/web-ui/build/static/julia-D0PJgQhi.js +0 -1
- package/web-ui/build/static/julia-repl-BLnLCve4.js +0 -1
- package/web-ui/build/static/keepalived-SvzEYloD.js +0 -1
- package/web-ui/build/static/keyman-B5l2mmmE.js +0 -1
- package/web-ui/build/static/kotlin-B_6COR1e.js +0 -1
- package/web-ui/build/static/kotlin-vd1Xdz6D.js +0 -1
- package/web-ui/build/static/kumir-8mIZWgJQ.js +0 -1
- package/web-ui/build/static/kusto-CoV2oHqt.js +0 -1
- package/web-ui/build/static/lasso-BjjUNa_o.js +0 -1
- package/web-ui/build/static/latex-C9KOfuFk.js +0 -1
- package/web-ui/build/static/latex-DhLttY-I.js +0 -1
- package/web-ui/build/static/latte-CaYNaOoK.js +0 -1
- package/web-ui/build/static/ldif-DFxnpH3G.js +0 -1
- package/web-ui/build/static/leaf-DrMpC83a.js +0 -1
- package/web-ui/build/static/less-DUoYpEFn.js +0 -1
- package/web-ui/build/static/less-nh0XCcut.js +0 -1
- package/web-ui/build/static/lilypond-BlqjLr3W.js +0 -1
- package/web-ui/build/static/liquid-BVGHSG0T.js +0 -1
- package/web-ui/build/static/lisp-CEK8BtYQ.js +0 -1
- package/web-ui/build/static/lisp-D_jGHxhc.js +0 -1
- package/web-ui/build/static/livecodeserver-CFUDw_SK.js +0 -1
- package/web-ui/build/static/livescript-C5xzpiLM.js +0 -1
- package/web-ui/build/static/livescript-CKoPcK0c.js +0 -1
- package/web-ui/build/static/llvm-BBOVIeTl.js +0 -1
- package/web-ui/build/static/llvm-ioC5bCUB.js +0 -1
- package/web-ui/build/static/log-CPYTqm4T.js +0 -1
- package/web-ui/build/static/lolcode-BkT93adT.js +0 -1
- package/web-ui/build/static/lsl-M98YPNRW.js +0 -1
- package/web-ui/build/static/lua-D7Lum5n9.js +0 -1
- package/web-ui/build/static/lua-DHyr0QwE.js +0 -1
- package/web-ui/build/static/magma-BwMFjwQu.js +0 -1
- package/web-ui/build/static/makefile-BFYZ-SfG.js +0 -1
- package/web-ui/build/static/makefile-D6oyR2lD.js +0 -1
- package/web-ui/build/static/markdown-6jtg6KZm.js +0 -1
- package/web-ui/build/static/markdown-DTLtPgeP.js +0 -1
- package/web-ui/build/static/markup-templating-K8uoAIqY.js +0 -1
- package/web-ui/build/static/mathematica-cW5hOuB2.js +0 -1
- package/web-ui/build/static/matlab-CwSNWEq8.js +0 -1
- package/web-ui/build/static/matlab-MQ972BY-.js +0 -1
- package/web-ui/build/static/maxima-CMSFLri-.js +0 -1
- package/web-ui/build/static/maxscript-BzcoS2KA.js +0 -1
- package/web-ui/build/static/mel-Cd20pAs-.js +0 -1
- package/web-ui/build/static/mel-KWG5N49g.js +0 -1
- package/web-ui/build/static/mercury-eW1ljJh0.js +0 -1
- package/web-ui/build/static/mermaid-D3zeCM84.js +0 -1
- package/web-ui/build/static/mipsasm-B5g6Ndra.js +0 -1
- package/web-ui/build/static/mizar-C_nZ0Ts9.js +0 -1
- package/web-ui/build/static/mizar-CuTNEv2t.js +0 -1
- package/web-ui/build/static/mojolicious-C1Xq--lT.js +0 -1
- package/web-ui/build/static/mongodb-C_3giArw.js +0 -1
- package/web-ui/build/static/monkey-DQ1olPd-.js +0 -1
- package/web-ui/build/static/monkey-n4Tbrep7.js +0 -1
- package/web-ui/build/static/moonscript-CmnQJuIL.js +0 -1
- package/web-ui/build/static/moonscript-DXgmWjLy.js +0 -1
- package/web-ui/build/static/n1ql-531a3W-1.js +0 -1
- package/web-ui/build/static/n1ql-BYH9EvME.js +0 -1
- package/web-ui/build/static/n4js-Cy0LcM-V.js +0 -1
- package/web-ui/build/static/nand2tetris-hdl-CKOztBDD.js +0 -1
- package/web-ui/build/static/naniscript-oLFpxBGE.js +0 -1
- package/web-ui/build/static/nasm-DLPnwFkM.js +0 -1
- package/web-ui/build/static/neon-Cn03wGUR.js +0 -1
- package/web-ui/build/static/nevod-C_VRvbdf.js +0 -1
- package/web-ui/build/static/nginx-60SpLv4t.js +0 -1
- package/web-ui/build/static/nginx-DZLHid-q.js +0 -1
- package/web-ui/build/static/nim-BnrHdqGC.js +0 -1
- package/web-ui/build/static/nim-Ds3pmwtE.js +0 -1
- package/web-ui/build/static/nix-Dl-dS0w4.js +0 -1
- package/web-ui/build/static/nix-jL62FzTz.js +0 -1
- package/web-ui/build/static/node-repl-BAuDzNZd.js +0 -1
- package/web-ui/build/static/nsis-CEnFjfNr.js +0 -1
- package/web-ui/build/static/nsis-CcCz6HIu.js +0 -1
- package/web-ui/build/static/objectivec-CZXfVowS.js +0 -1
- package/web-ui/build/static/objectivec-CuaFU-Ef.js +0 -1
- package/web-ui/build/static/ocaml-BGAzfwAx.js +0 -1
- package/web-ui/build/static/ocaml-BoO1lU26.js +0 -1
- package/web-ui/build/static/opencl-DAnD5xP-.js +0 -1
- package/web-ui/build/static/openqasm-CO7gdVj9.js +0 -1
- package/web-ui/build/static/openscad-B2wMEMQR.js +0 -1
- package/web-ui/build/static/oxygene-1erv93gF.js +0 -1
- package/web-ui/build/static/oz-D3334gi7.js +0 -1
- package/web-ui/build/static/parigp-rQZTN8zi.js +0 -1
- package/web-ui/build/static/parser-B4ZSZ1ig.js +0 -1
- package/web-ui/build/static/parser3-CCCjkYLG.js +0 -1
- package/web-ui/build/static/pascal-DeC9Pvom.js +0 -1
- package/web-ui/build/static/pascaligo-CT2u6UpO.js +0 -1
- package/web-ui/build/static/pcaxis-CvlRg6t4.js +0 -1
- package/web-ui/build/static/peoplecode-BYahULz2.js +0 -1
- package/web-ui/build/static/perl-CKgvyY59.js +0 -1
- package/web-ui/build/static/perl-E7sx7Izv.js +0 -1
- package/web-ui/build/static/pf-D9wnFBt7.js +0 -1
- package/web-ui/build/static/pgsql-CrlBdRAn.js +0 -1
- package/web-ui/build/static/php-D2O-B3y7.js +0 -1
- package/web-ui/build/static/php-extras-BKqZuzgt.js +0 -1
- package/web-ui/build/static/php-nfXl9WfB.js +0 -1
- package/web-ui/build/static/php-template-Cg8ERLNQ.js +0 -1
- package/web-ui/build/static/phpdoc-Z1u90OwH.js +0 -1
- package/web-ui/build/static/plaintext-DkNVeXWx.js +0 -1
- package/web-ui/build/static/plsql-DO5fJNhS.js +0 -1
- package/web-ui/build/static/pony-DXIqq5Bk.js +0 -1
- package/web-ui/build/static/powerquery-B2ovxJZi.js +0 -1
- package/web-ui/build/static/powershell-BVeqqari.js +0 -1
- package/web-ui/build/static/powershell-CskV4qWh.js +0 -1
- package/web-ui/build/static/processing-D90SJpnq.js +0 -1
- package/web-ui/build/static/processing-DP2mf97Z.js +0 -1
- package/web-ui/build/static/profile-H6zk8v_f.js +0 -1
- package/web-ui/build/static/prolog-AUfxYiJV.js +0 -1
- package/web-ui/build/static/prolog-Dz2WdsVN.js +0 -1
- package/web-ui/build/static/promql-CloMJmMW.js +0 -1
- package/web-ui/build/static/properties-CTl3mnrP.js +0 -1
- package/web-ui/build/static/properties-D2RfteTZ.js +0 -1
- package/web-ui/build/static/protobuf-Be9oqQCu.js +0 -1
- package/web-ui/build/static/protobuf-BgG8zUnY.js +0 -1
- package/web-ui/build/static/psl-Bqx8iN9e.js +0 -1
- package/web-ui/build/static/pug-CHfFC0Wg.js +0 -1
- package/web-ui/build/static/puppet-__1ifzZS.js +0 -1
- package/web-ui/build/static/puppet-pbtRCMgd.js +0 -1
- package/web-ui/build/static/pure-B9STuf4F.js +0 -1
- package/web-ui/build/static/purebasic-7ADyn-Ce.js +0 -1
- package/web-ui/build/static/purebasic-Bc06YQcD.js +0 -1
- package/web-ui/build/static/purescript-CU-dDebr.js +0 -1
- package/web-ui/build/static/python-BEsXrEbi.js +0 -1
- package/web-ui/build/static/python-CZFrgH2X.js +0 -1
- package/web-ui/build/static/python-repl-CI9GmJce.js +0 -1
- package/web-ui/build/static/q-E7xvTGRo.js +0 -1
- package/web-ui/build/static/q-hvg9aQoY.js +0 -1
- package/web-ui/build/static/qml-DkZWcxEv.js +0 -1
- package/web-ui/build/static/qml-DpdWla8G.js +0 -1
- package/web-ui/build/static/qore-Dsm7ACR_.js +0 -1
- package/web-ui/build/static/qsharp-BBec6MJR.js +0 -1
- package/web-ui/build/static/r-CTVkq_Ky.js +0 -1
- package/web-ui/build/static/r-DHGNCupF.js +0 -1
- package/web-ui/build/static/racket-hoSh4YPx.js +0 -1
- package/web-ui/build/static/reason-CQPUIbsm.js +0 -1
- package/web-ui/build/static/reasonml-BXtFFSTZ.js +0 -1
- package/web-ui/build/static/regex-BNkF_ufb.js +0 -1
- package/web-ui/build/static/rego-BXHrjItC.js +0 -1
- package/web-ui/build/static/renpy-CBQvK_5t.js +0 -1
- package/web-ui/build/static/rest-Bf8hzmF1.js +0 -1
- package/web-ui/build/static/rib-D0a4KzlP.js +0 -1
- package/web-ui/build/static/rip-DchN4BQN.js +0 -1
- package/web-ui/build/static/roboconf-HXnyGNTm.js +0 -1
- package/web-ui/build/static/roboconf-zfK6mgmU.js +0 -1
- package/web-ui/build/static/robotframework-DnP-vXyd.js +0 -1
- package/web-ui/build/static/routeros-CDirYxZY.js +0 -1
- package/web-ui/build/static/rsl-BCK_msc-.js +0 -1
- package/web-ui/build/static/ruby--mXX6GNK.js +0 -1
- package/web-ui/build/static/ruby-BIdQYq0Y.js +0 -1
- package/web-ui/build/static/ruleslanguage-BD07s5RU.js +0 -1
- package/web-ui/build/static/rust-Bgni9V7U.js +0 -1
- package/web-ui/build/static/rust-OywmQ2ox.js +0 -1
- package/web-ui/build/static/sas-B6-82htH.js +0 -1
- package/web-ui/build/static/sas-k9XEScbR.js +0 -1
- package/web-ui/build/static/sass-BOvNBStT.js +0 -1
- package/web-ui/build/static/scala-At07fmMd.js +0 -1
- package/web-ui/build/static/scala-DUOfqSaU.js +0 -1
- package/web-ui/build/static/scheme-B87lC0bK.js +0 -1
- package/web-ui/build/static/scheme-BS7OzWRX.js +0 -1
- package/web-ui/build/static/scilab-Bmn4jjcu.js +0 -1
- package/web-ui/build/static/scss-DTeB95yE.js +0 -1
- package/web-ui/build/static/scss-xilnl6Dx.js +0 -1
- package/web-ui/build/static/shell-CKetyy4y.js +0 -1
- package/web-ui/build/static/shell-session-B6rat2c7.js +0 -1
- package/web-ui/build/static/smali-C9O9CXOD.js +0 -1
- package/web-ui/build/static/smali-CBkgbinS.js +0 -1
- package/web-ui/build/static/smalltalk-CuUjFHiz.js +0 -1
- package/web-ui/build/static/smalltalk-D0xhFL9b.js +0 -1
- package/web-ui/build/static/smarty-CY0N0d5x.js +0 -1
- package/web-ui/build/static/sml-BVAw3fjB.js +0 -1
- package/web-ui/build/static/sml-CO9XB1ax.js +0 -1
- package/web-ui/build/static/solidity-BNixD4Dx.js +0 -1
- package/web-ui/build/static/solution-file-DHyGXf2y.js +0 -1
- package/web-ui/build/static/soy-Cxgjntsl.js +0 -1
- package/web-ui/build/static/sparql-CDLqu9vy.js +0 -1
- package/web-ui/build/static/splunk-spl-Cmkl_Xmw.js +0 -1
- package/web-ui/build/static/sqf-CIGKolw3.js +0 -1
- package/web-ui/build/static/sqf-Cfp_lC6-.js +0 -1
- package/web-ui/build/static/sql-DHOGwYxe.js +0 -1
- package/web-ui/build/static/sql-QIw1Q2yi.js +0 -1
- package/web-ui/build/static/sql_more-C0b3-InT.js +0 -1
- package/web-ui/build/static/squirrel-DASToo1F.js +0 -1
- package/web-ui/build/static/stan-DHMkcFZg.js +0 -1
- package/web-ui/build/static/stan-No3nsdnQ.js +0 -1
- package/web-ui/build/static/stata-Brkzu5Nv.js +0 -1
- package/web-ui/build/static/step21-D2l5M5Ml.js +0 -1
- package/web-ui/build/static/stylus-Bx6FaZN_.js +0 -1
- package/web-ui/build/static/stylus-CVkTaPns.js +0 -1
- package/web-ui/build/static/subunit-CDrsAMuL.js +0 -1
- package/web-ui/build/static/swift-BSw_pS-l.js +0 -1
- package/web-ui/build/static/swift-BWyqwIo8.js +0 -1
- package/web-ui/build/static/systemd-BwqpYcJK.js +0 -1
- package/web-ui/build/static/t4-cs-CwsJLOxV.js +0 -1
- package/web-ui/build/static/t4-templating-BfxY01xf.js +0 -1
- package/web-ui/build/static/t4-vb-BhsKKFhp.js +0 -1
- package/web-ui/build/static/taggerscript-Bkew95or.js +0 -1
- package/web-ui/build/static/tap-DHovcHbS.js +0 -1
- package/web-ui/build/static/tap-DPl9uPo4.js +0 -1
- package/web-ui/build/static/tcl-BeozHO-f.js +0 -1
- package/web-ui/build/static/tcl-Df_8ItQH.js +0 -1
- package/web-ui/build/static/textile-B3m_f58b.js +0 -1
- package/web-ui/build/static/thrift-D20n-HpW.js +0 -1
- package/web-ui/build/static/toml-C-fTAonK.js +0 -1
- package/web-ui/build/static/tp-hGbXe5Eo.js +0 -1
- package/web-ui/build/static/tremor-BaVOtRFz.js +0 -1
- package/web-ui/build/static/tsx-ChPInNl0.js +0 -1
- package/web-ui/build/static/tt2-DAIJ8cpz.js +0 -1
- package/web-ui/build/static/turtle-B7z_y-PK.js +0 -1
- package/web-ui/build/static/twig-TUEkve6W.js +0 -1
- package/web-ui/build/static/twig-stKDItz7.js +0 -1
- package/web-ui/build/static/typescript-BPdM-QOM.js +0 -1
- package/web-ui/build/static/typescript-DjSY4MvL.js +0 -1
- package/web-ui/build/static/typoscript-BQHgQtEL.js +0 -1
- package/web-ui/build/static/unrealscript-g8yNPQQ5.js +0 -1
- package/web-ui/build/static/uorazor-CnuMiQz9.js +0 -1
- package/web-ui/build/static/uri-CfioiemU.js +0 -1
- package/web-ui/build/static/v-B69Oau14.js +0 -1
- package/web-ui/build/static/vala-C0PjlK3l.js +0 -1
- package/web-ui/build/static/vala-COgjD3gU.js +0 -1
- package/web-ui/build/static/vbnet-CklOnyuR.js +0 -1
- package/web-ui/build/static/vbnet-MxHUC5Mz.js +0 -1
- package/web-ui/build/static/vbscript-BxQnA97w.js +0 -1
- package/web-ui/build/static/vbscript-html-DOtde7dD.js +0 -1
- package/web-ui/build/static/velocity-l8B9m66X.js +0 -1
- package/web-ui/build/static/verilog-DF6dF-Vp.js +0 -1
- package/web-ui/build/static/verilog-Dgb9SDRX.js +0 -1
- package/web-ui/build/static/vhdl-0GarU_AK.js +0 -1
- package/web-ui/build/static/vhdl-BfPQnOdI.js +0 -1
- package/web-ui/build/static/vim-Likg_-II.js +0 -1
- package/web-ui/build/static/vim-k53Sj7A3.js +0 -1
- package/web-ui/build/static/visual-basic-BNVZCzlV.js +0 -1
- package/web-ui/build/static/warpscript-BkLK5iuW.js +0 -1
- package/web-ui/build/static/wasm-CQhA1ece.js +0 -1
- package/web-ui/build/static/web-idl-DmNsI0kE.js +0 -1
- package/web-ui/build/static/wiki-B3z4pmra.js +0 -1
- package/web-ui/build/static/wolfram-Dsf21d_g.js +0 -1
- package/web-ui/build/static/wren-BZXZlzrL.js +0 -1
- package/web-ui/build/static/x86asm-DpWGZhJU.js +0 -1
- package/web-ui/build/static/xeora-8xPZN4DH.js +0 -1
- package/web-ui/build/static/xl-XkdWYMGl.js +0 -1
- package/web-ui/build/static/xml-BBdROEWt.js +0 -1
- package/web-ui/build/static/xml-doc-Cjs4OpTe.js +0 -1
- package/web-ui/build/static/xojo-nCen1FPx.js +0 -1
- package/web-ui/build/static/xquery-CBFkAxo1.js +0 -1
- package/web-ui/build/static/xquery-Dwsc1weX.js +0 -1
- package/web-ui/build/static/yaml-DzSAh6jl.js +0 -1
- package/web-ui/build/static/yaml-Lg8gnEUU.js +0 -1
- package/web-ui/build/static/yang-Bd-v2b0k.js +0 -1
- package/web-ui/build/static/zephir-wbJOizIa.js +0 -1
- package/web-ui/build/static/zig-Cz384XjE.js +0 -1
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Account & API-key management routes on the local CLI server.
|
|
3
|
+
*
|
|
4
|
+
* These are thin proxies over the autopilot-backend's `/auth/*` and
|
|
5
|
+
* `/account/*` endpoints. The local server holds the user's JWT in
|
|
6
|
+
* `lastAuthResult.jwt` (encrypted on disk via authCacheStore) and
|
|
7
|
+
* forwards it as a `Authorization: Bearer` to the backend. The web-ui
|
|
8
|
+
* never sees the JWT after the initial OAuth landing — keeping it on
|
|
9
|
+
* the local-server side means:
|
|
10
|
+
*
|
|
11
|
+
* 1. No CORS dance between the browser and Azure backend.
|
|
12
|
+
* 2. The web-ui can talk to one origin (its own).
|
|
13
|
+
* 3. A compromised renderer cannot exfiltrate the bearer in plaintext
|
|
14
|
+
* (it lives in localStorage, but everything that NEEDS it goes
|
|
15
|
+
* through the local server).
|
|
16
|
+
* 4. Symmetric with the existing marketplaceApi pattern.
|
|
17
|
+
*
|
|
18
|
+
* Endpoints (mounted by webServer.js at boot):
|
|
19
|
+
* GET /api/account/profile — proxies /auth/me
|
|
20
|
+
* GET /api/account/balance — proxies /account/balance (ledger)
|
|
21
|
+
* GET /api/account/keys — proxies /auth/apikeys
|
|
22
|
+
* POST /api/account/keys — proxies /auth/apikey (one-time-reveal body)
|
|
23
|
+
* DELETE /api/account/keys/:id — proxies /auth/apikey/:id
|
|
24
|
+
* POST /api/account/handoff — mints + returns a portal handoff URL
|
|
25
|
+
*
|
|
26
|
+
* Auth: each route requires `lastAuthResult.jwt` to be present. When
|
|
27
|
+
* the user hasn't OAuth'd yet, we return 401 with a clear `code` the
|
|
28
|
+
* FE can branch on ('not_signed_in') so it can prompt for sign-in
|
|
29
|
+
* rather than show a generic error.
|
|
30
|
+
*
|
|
31
|
+
* Security guarantees:
|
|
32
|
+
* - The local server never returns the JWT to the renderer.
|
|
33
|
+
* - The API-key create endpoint returns the `lx_*` value exactly
|
|
34
|
+
* once (mirroring the backend); subsequent list calls show only
|
|
35
|
+
* metadata + a masked key.
|
|
36
|
+
* - The handoff URL embeds a single-use short-lived token, NOT the
|
|
37
|
+
* long-lived JWT.
|
|
38
|
+
* - All errors are normalised to `{ success: false, error, code? }`
|
|
39
|
+
* so the FE never has to special-case axios vs fetch envelopes.
|
|
40
|
+
*
|
|
41
|
+
* Testable design:
|
|
42
|
+
* `createAccountRouter()` accepts every dependency it needs (fetch
|
|
43
|
+
* impl, backend URL, JWT getter, logger). Production builds inject
|
|
44
|
+
* the real ones; tests inject stubs. See accountRoutes.test.js.
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
import express from 'express';
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Default backend URL — overridable via the same `config.backend.baseUrl`
|
|
51
|
+
* the existing /auth routes use, so a single env-config change moves
|
|
52
|
+
* every backend call to staging or local-dev.
|
|
53
|
+
*/
|
|
54
|
+
const DEFAULT_BACKEND_URL = 'https://autopilot-api.azurewebsites.net';
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Portal URL per brand. The handoff endpoint uses this to construct
|
|
58
|
+
* the deep-link the FE opens in the system browser. Two reasons we
|
|
59
|
+
* pick the brand at construction time, not request time:
|
|
60
|
+
* - The local server already knows its brand (loaded at boot).
|
|
61
|
+
* - The renderer should never get to influence which portal we send
|
|
62
|
+
* the user to (mitigation against open-redirect via a tampered
|
|
63
|
+
* request body).
|
|
64
|
+
*/
|
|
65
|
+
const PORTAL_URLS_BY_BRAND = Object.freeze({
|
|
66
|
+
autopilot: 'https://autopilot.loxia.ai',
|
|
67
|
+
onbuzz: 'https://onbuzz.loxia.ai',
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Codes the FE branches on. Keep this list in lockstep with web-ui's
|
|
72
|
+
* account API client. New codes must be added to the FE's switch.
|
|
73
|
+
*/
|
|
74
|
+
export const ERROR_CODES = Object.freeze({
|
|
75
|
+
NOT_SIGNED_IN: 'not_signed_in',
|
|
76
|
+
BACKEND_ERROR: 'backend_error',
|
|
77
|
+
NETWORK_ERROR: 'network_error',
|
|
78
|
+
BAD_REQUEST: 'bad_request',
|
|
79
|
+
NOT_FOUND: 'not_found',
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Build the account router. Pure DI — every external concern is a
|
|
84
|
+
* function the caller passes in.
|
|
85
|
+
*
|
|
86
|
+
* @param {Object} deps
|
|
87
|
+
* @param {() => string|null} deps.getJwt
|
|
88
|
+
* Returns the user's current JWT or null when unauthenticated.
|
|
89
|
+
* Caller hooks this to `() => webServer.lastAuthResult?.jwt`.
|
|
90
|
+
* @param {() => string} deps.getBrand
|
|
91
|
+
* Returns 'autopilot' | 'onbuzz'. Used to pick portal URL.
|
|
92
|
+
* @param {string} [deps.backendBaseUrl]
|
|
93
|
+
* @param {typeof fetch} [deps.fetchImpl]
|
|
94
|
+
* @param {Object} [deps.logger]
|
|
95
|
+
*/
|
|
96
|
+
export function createAccountRouter({
|
|
97
|
+
getJwt,
|
|
98
|
+
getBrand,
|
|
99
|
+
backendBaseUrl = DEFAULT_BACKEND_URL,
|
|
100
|
+
fetchImpl = fetch,
|
|
101
|
+
logger = console,
|
|
102
|
+
} = {}) {
|
|
103
|
+
if (typeof getJwt !== 'function') throw new Error('createAccountRouter: getJwt is required');
|
|
104
|
+
if (typeof getBrand !== 'function') throw new Error('createAccountRouter: getBrand is required');
|
|
105
|
+
|
|
106
|
+
const router = express.Router();
|
|
107
|
+
const baseUrl = backendBaseUrl.replace(/\/$/, '');
|
|
108
|
+
|
|
109
|
+
// Last-known-good balance cache, per JWT (so a fast user-switch
|
|
110
|
+
// doesn't show the previous user's balance). Stays in memory only —
|
|
111
|
+
// a server restart wipes it, by design: stale-on-disk balance would
|
|
112
|
+
// be more dangerous than no balance.
|
|
113
|
+
/** @type {Map<string, { balance: number, plan: string|null, savedAt: string }>} */
|
|
114
|
+
const balanceCache = new Map();
|
|
115
|
+
function cacheKey(jwt) {
|
|
116
|
+
if (!jwt) return null;
|
|
117
|
+
// Hash the JWT to keep memory footprint sane (JWTs are ~240 chars
|
|
118
|
+
// each). The hash is a fingerprint, not used as auth.
|
|
119
|
+
let h = 0; for (let i = 0; i < jwt.length; i++) { h = ((h << 5) - h + jwt.charCodeAt(i)) | 0; }
|
|
120
|
+
return String(h);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Coerce whatever the upstream put under `body.error` into a
|
|
125
|
+
* human-readable string. Different upstream services use different
|
|
126
|
+
* envelope shapes — string, `{message,code}`, or even nested objects.
|
|
127
|
+
* Always returns a string so the FE's `title="..."` tooltip never
|
|
128
|
+
* shows `[object Object]`.
|
|
129
|
+
*/
|
|
130
|
+
function extractErrorMessage(body) {
|
|
131
|
+
if (!body) return '';
|
|
132
|
+
const err = body.error;
|
|
133
|
+
if (typeof err === 'string') return err;
|
|
134
|
+
if (err && typeof err === 'object') {
|
|
135
|
+
if (typeof err.message === 'string') return err.message;
|
|
136
|
+
if (typeof err.code === 'string') return err.code;
|
|
137
|
+
try { return JSON.stringify(err); } catch { return ''; }
|
|
138
|
+
}
|
|
139
|
+
if (typeof body.message === 'string') return body.message;
|
|
140
|
+
return '';
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Forward a request to the backend with the user's JWT. Returns a
|
|
145
|
+
* { status, body } tuple the route handlers can hand straight back
|
|
146
|
+
* to Express, normalising every transport failure into the same
|
|
147
|
+
* envelope.
|
|
148
|
+
*/
|
|
149
|
+
async function proxyToBackend(method, path, body) {
|
|
150
|
+
const jwt = getJwt();
|
|
151
|
+
if (!jwt) {
|
|
152
|
+
return {
|
|
153
|
+
status: 401,
|
|
154
|
+
body: { success: false, error: 'Sign in to manage your account', code: ERROR_CODES.NOT_SIGNED_IN },
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
const url = `${baseUrl}${path}`;
|
|
158
|
+
try {
|
|
159
|
+
const t0 = Date.now();
|
|
160
|
+
const res = await fetchImpl(url, {
|
|
161
|
+
method,
|
|
162
|
+
headers: {
|
|
163
|
+
'Authorization': `Bearer ${jwt}`,
|
|
164
|
+
'Content-Type': 'application/json',
|
|
165
|
+
'Connection': 'close',
|
|
166
|
+
},
|
|
167
|
+
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
const text = await res.text();
|
|
171
|
+
let parsed;
|
|
172
|
+
try { parsed = text ? JSON.parse(text) : {}; } catch { parsed = { raw: text }; }
|
|
173
|
+
|
|
174
|
+
// Per-request debug log so a flaky upstream is diagnosable
|
|
175
|
+
// without reproducing in a separate process. Worth the noise
|
|
176
|
+
// because the account proxy currently has an unsolved
|
|
177
|
+
// discrepancy: standalone Node script gets 200s, the in-process
|
|
178
|
+
// fetch gets 5xxs against the same URL with the same JWT.
|
|
179
|
+
logger?.info?.('[accountRoutes] upstream', {
|
|
180
|
+
url,
|
|
181
|
+
method,
|
|
182
|
+
status: res.status,
|
|
183
|
+
ms: Date.now() - t0,
|
|
184
|
+
bodyPreview: typeof text === 'string' ? text.slice(0, 200) : null,
|
|
185
|
+
contentType: res.headers?.get?.('content-type') || null,
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
if (!res.ok) {
|
|
189
|
+
return {
|
|
190
|
+
status: res.status,
|
|
191
|
+
body: {
|
|
192
|
+
success: false,
|
|
193
|
+
error: extractErrorMessage(parsed) || `Backend returned ${res.status}`,
|
|
194
|
+
code: res.status === 404 ? ERROR_CODES.NOT_FOUND : ERROR_CODES.BACKEND_ERROR,
|
|
195
|
+
},
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
return { status: res.status, body: parsed };
|
|
199
|
+
} catch (err) {
|
|
200
|
+
logger?.warn?.('[accountRoutes] backend fetch failed', { method, path, error: err.message });
|
|
201
|
+
return {
|
|
202
|
+
status: 503,
|
|
203
|
+
body: {
|
|
204
|
+
success: false,
|
|
205
|
+
error: 'Could not reach the account service. Try again in a moment.',
|
|
206
|
+
code: ERROR_CODES.NETWORK_ERROR,
|
|
207
|
+
},
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// ── Debug ──────────────────────────────────────────────────────────
|
|
213
|
+
// Temporary diagnostic route. Returns the raw responses from each
|
|
214
|
+
// upstream call the cascade makes so we can see in the browser why
|
|
215
|
+
// /balance falls through to degraded when standalone fetch from the
|
|
216
|
+
// same machine works fine. Remove when the balance issue is closed.
|
|
217
|
+
router.get('/_debug', async (_req, res) => {
|
|
218
|
+
const jwt = getJwt();
|
|
219
|
+
if (!jwt) return res.status(401).json({ error: 'not signed in' });
|
|
220
|
+
const probe = async (path) => {
|
|
221
|
+
const url = `${baseUrl}${path}`;
|
|
222
|
+
const t0 = Date.now();
|
|
223
|
+
try {
|
|
224
|
+
const r = await fetchImpl(url, {
|
|
225
|
+
method: 'GET',
|
|
226
|
+
headers: {
|
|
227
|
+
'Authorization': `Bearer ${jwt}`,
|
|
228
|
+
'Content-Type': 'application/json',
|
|
229
|
+
'Connection': 'close',
|
|
230
|
+
},
|
|
231
|
+
});
|
|
232
|
+
const text = await r.text();
|
|
233
|
+
return {
|
|
234
|
+
path, url, status: r.status, ms: Date.now() - t0,
|
|
235
|
+
contentType: r.headers?.get?.('content-type') || null,
|
|
236
|
+
bodyPreview: text.slice(0, 400),
|
|
237
|
+
};
|
|
238
|
+
} catch (err) {
|
|
239
|
+
return { path, url, ms: Date.now() - t0, error: err.message, errCode: err.code, errName: err.name };
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
res.json({
|
|
243
|
+
baseUrl,
|
|
244
|
+
jwtLen: jwt.length,
|
|
245
|
+
probes: await Promise.all([
|
|
246
|
+
probe('/subscription/status'),
|
|
247
|
+
probe('/account/profile'),
|
|
248
|
+
probe('/auth/me'),
|
|
249
|
+
]),
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
// ── Profile ────────────────────────────────────────────────────────
|
|
254
|
+
router.get('/profile', async (_req, res) => {
|
|
255
|
+
const r = await proxyToBackend('GET', '/auth/me');
|
|
256
|
+
// /auth/me returns either `{ user: {...} }` or `{...userFields}`.
|
|
257
|
+
// Normalise so the FE always sees `{ user: {...} }`.
|
|
258
|
+
if (r.status === 200) {
|
|
259
|
+
const u = r.body?.user || r.body;
|
|
260
|
+
return res.json({ success: true, user: u });
|
|
261
|
+
}
|
|
262
|
+
res.status(r.status).json(r.body);
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
// ── Balance ────────────────────────────────────────────────────────
|
|
266
|
+
// Reads `{ plan, balance, ... }` from the backend.
|
|
267
|
+
//
|
|
268
|
+
// Endpoint cascade — first one that returns 2xx wins:
|
|
269
|
+
// 1. /subscription/status — returns { plan, balance, monthlyAllocation,
|
|
270
|
+
// subscriptionStatus, currentPeriodEnd }. Reads from User.creditBalance
|
|
271
|
+
// (cached / DB-direct) so it works even when the ledger is down.
|
|
272
|
+
// This is the PRIMARY because of that resilience.
|
|
273
|
+
// 2. /account/profile — bundles plan + balance from the ledger.
|
|
274
|
+
// Richer data, but 500s if LEDGER_SERVICE_URL is missing.
|
|
275
|
+
// 3. /auth/me — no balance, but at least we can return plan + null.
|
|
276
|
+
//
|
|
277
|
+
// The FE never sees an error here — degraded data + a `degraded: true`
|
|
278
|
+
// flag is the right UX, not an error toast.
|
|
279
|
+
router.get('/balance', async (_req, res) => {
|
|
280
|
+
// Balance is a per-user query — needs a JWT just like every other
|
|
281
|
+
// /api/account/* route. Early-exit with the same not_signed_in
|
|
282
|
+
// envelope so the FE branches the same way.
|
|
283
|
+
const jwt = getJwt();
|
|
284
|
+
if (!jwt) {
|
|
285
|
+
return res.status(401).json({
|
|
286
|
+
success: false,
|
|
287
|
+
error: 'Sign in to manage your account',
|
|
288
|
+
code: ERROR_CODES.NOT_SIGNED_IN,
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
const ck = cacheKey(jwt);
|
|
292
|
+
|
|
293
|
+
const subscription = await proxyToBackend('GET', '/subscription/status');
|
|
294
|
+
if (subscription.status >= 200 && subscription.status < 300) {
|
|
295
|
+
const body = subscription.body || {};
|
|
296
|
+
if (typeof body.balance === 'number') {
|
|
297
|
+
balanceCache.set(ck, { balance: body.balance, plan: body.plan || null, savedAt: new Date().toISOString() });
|
|
298
|
+
}
|
|
299
|
+
return res.status(subscription.status).json(body);
|
|
300
|
+
}
|
|
301
|
+
const profile = await proxyToBackend('GET', '/account/profile');
|
|
302
|
+
if (profile.status >= 200 && profile.status < 300) {
|
|
303
|
+
const body = profile.body || {};
|
|
304
|
+
if (typeof body.balance === 'number') {
|
|
305
|
+
balanceCache.set(ck, { balance: body.balance, plan: body.plan || body.accountType || null, savedAt: new Date().toISOString() });
|
|
306
|
+
}
|
|
307
|
+
return res.status(profile.status).json(body);
|
|
308
|
+
}
|
|
309
|
+
// Both balance-bearing endpoints failed. Hand back the last-known
|
|
310
|
+
// good value (if any) with a `stale: true` flag so the FE shows a
|
|
311
|
+
// number instead of "— CP". The user still gets a visual cue that
|
|
312
|
+
// it might not be current.
|
|
313
|
+
const cached = balanceCache.get(ck);
|
|
314
|
+
const me = await proxyToBackend('GET', '/auth/me');
|
|
315
|
+
const u = me.status >= 200 && me.status < 300 ? (me.body?.user || me.body || {}) : {};
|
|
316
|
+
|
|
317
|
+
// The internal ECONNREFUSED string is useful for debugging but
|
|
318
|
+
// not for users — log it once at warn, surface a friendly reason.
|
|
319
|
+
const technical = extractErrorMessage(subscription.body) || extractErrorMessage(profile.body) || '';
|
|
320
|
+
if (technical) logger?.warn?.('[accountRoutes] balance degraded', { technical });
|
|
321
|
+
|
|
322
|
+
res.json({
|
|
323
|
+
balance: cached ? cached.balance : (typeof u.creditBalance === 'number' ? u.creditBalance : null),
|
|
324
|
+
plan: cached?.plan || u.accountType || null,
|
|
325
|
+
degraded: true,
|
|
326
|
+
stale: !!cached,
|
|
327
|
+
lastUpdatedAt: cached?.savedAt || null,
|
|
328
|
+
reason: 'Balance service is temporarily unavailable',
|
|
329
|
+
});
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
// ── API keys list ──────────────────────────────────────────────────
|
|
333
|
+
router.get('/keys', async (_req, res) => {
|
|
334
|
+
const r = await proxyToBackend('GET', '/auth/apikeys');
|
|
335
|
+
res.status(r.status).json(r.body);
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
// ── API key create ────────────────────────────────────────────────
|
|
339
|
+
router.post('/keys', express.json(), async (req, res) => {
|
|
340
|
+
const { name, expiresIn } = req.body || {};
|
|
341
|
+
if (!name || typeof name !== 'string' || !name.trim()) {
|
|
342
|
+
return res.status(400).json({
|
|
343
|
+
success: false,
|
|
344
|
+
error: 'Provide a name to identify the key',
|
|
345
|
+
code: ERROR_CODES.BAD_REQUEST,
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
const payload = { name: name.trim() };
|
|
349
|
+
if (expiresIn != null) payload.expiresIn = expiresIn;
|
|
350
|
+
const r = await proxyToBackend('POST', '/auth/apikey', payload);
|
|
351
|
+
res.status(r.status).json(r.body);
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
// ── API key revoke ────────────────────────────────────────────────
|
|
355
|
+
router.delete('/keys/:id', async (req, res) => {
|
|
356
|
+
const id = req.params.id;
|
|
357
|
+
if (!id || !/^[a-zA-Z0-9_-]+$/.test(id)) {
|
|
358
|
+
return res.status(400).json({
|
|
359
|
+
success: false,
|
|
360
|
+
error: 'Invalid key id',
|
|
361
|
+
code: ERROR_CODES.BAD_REQUEST,
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
const r = await proxyToBackend('DELETE', `/auth/apikey/${encodeURIComponent(id)}`);
|
|
365
|
+
res.status(r.status).json(r.body);
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
// ── Portal handoff (Buy Credits) ──────────────────────────────────
|
|
369
|
+
router.post('/handoff', async (req, res) => {
|
|
370
|
+
const { destination } = req.body || {};
|
|
371
|
+
// Closed allowlist — never let the renderer drive arbitrary portal
|
|
372
|
+
// paths. New destinations must be added here intentionally.
|
|
373
|
+
const ALLOWED_DESTINATIONS = ['payment', 'subscription', 'api-keys', 'account'];
|
|
374
|
+
const path = destination && ALLOWED_DESTINATIONS.includes(destination) ? destination : 'payment';
|
|
375
|
+
|
|
376
|
+
const r = await proxyToBackend('POST', '/auth/handoff-token', { purpose: `portal-${path}` });
|
|
377
|
+
if (r.status !== 200 && r.status !== 201) {
|
|
378
|
+
return res.status(r.status).json(r.body);
|
|
379
|
+
}
|
|
380
|
+
const handoff = r.body?.handoff || r.body?.token;
|
|
381
|
+
if (!handoff) {
|
|
382
|
+
return res.status(502).json({
|
|
383
|
+
success: false,
|
|
384
|
+
error: 'Backend did not return a handoff token',
|
|
385
|
+
code: ERROR_CODES.BACKEND_ERROR,
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
const brand = getBrand();
|
|
389
|
+
const portalBase = PORTAL_URLS_BY_BRAND[brand] || PORTAL_URLS_BY_BRAND.autopilot;
|
|
390
|
+
const url = `${portalBase}/${path}?handoff=${encodeURIComponent(handoff)}`;
|
|
391
|
+
res.json({ success: true, url });
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
return router;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// Exported so tests + future routes can re-use it.
|
|
398
|
+
export const __test__ = { PORTAL_URLS_BY_BRAND, DEFAULT_BACKEND_URL };
|
|
@@ -33,6 +33,9 @@ import { getGalleryService } from '../services/galleryService.js';
|
|
|
33
33
|
import { getUserDataPaths } from '../utilities/userDataDir.js';
|
|
34
34
|
import { projectActiveRuns } from '../utilities/flowRunFilters.js';
|
|
35
35
|
import { recordOAuthResult, recordResolvedUser, projectAuthStatus } from '../utilities/authCache.js';
|
|
36
|
+
import AuthCacheStore from '../services/authCacheStore.js';
|
|
37
|
+
import { createAccountRouter } from './accountRoutes.js';
|
|
38
|
+
import { getBrand } from '../utilities/brand.js';
|
|
36
39
|
|
|
37
40
|
// Connect visual editor server to bridge (enables element selection forwarding)
|
|
38
41
|
setBridgeGetter(getVisualEditorBridge);
|
|
@@ -419,8 +422,15 @@ class WebServer {
|
|
|
419
422
|
// API Key Manager reference (will be set by LoxiaSystem)
|
|
420
423
|
this.apiKeyManager = null;
|
|
421
424
|
|
|
422
|
-
// Cached auth result for polling support (set by /auth/callback, cleared by /auth/signout)
|
|
423
|
-
|
|
425
|
+
// Cached auth result for polling support (set by /auth/callback, cleared by /auth/signout).
|
|
426
|
+
// Shape: { user, hasApiKey, jwt, timestamp }. The JWT is the critical
|
|
427
|
+
// field for marketplace publish/install/rate calls — see authCache.js.
|
|
428
|
+
// Persisted encrypted to <userDataDir>/settings/auth-cache.enc via
|
|
429
|
+
// `authCacheStore` so a server restart no longer wipes the JWT.
|
|
430
|
+
// Use `_setLastAuthResult(value)` rather than assigning directly so
|
|
431
|
+
// every mutation hits disk too.
|
|
432
|
+
this.lastAuthResult = null;
|
|
433
|
+
this.authCacheStore = new AuthCacheStore(this.logger);
|
|
424
434
|
|
|
425
435
|
// Credential Vault for secure credential management
|
|
426
436
|
this.credentialVault = null;
|
|
@@ -447,6 +457,20 @@ class WebServer {
|
|
|
447
457
|
*/
|
|
448
458
|
async initialize() {
|
|
449
459
|
try {
|
|
460
|
+
// Restore the persisted auth cache (JWT + user) so a server restart
|
|
461
|
+
// doesn't strand the FE without a token. Best-effort: a missing or
|
|
462
|
+
// corrupted file just leaves `lastAuthResult` at null.
|
|
463
|
+
await this.authCacheStore.initialize();
|
|
464
|
+
const restored = await this.authCacheStore.load();
|
|
465
|
+
if (restored) {
|
|
466
|
+
this.lastAuthResult = restored;
|
|
467
|
+
this.logger?.info?.('[WebServer] Restored auth cache from disk', {
|
|
468
|
+
hasUser: !!restored.user,
|
|
469
|
+
hasJwt: !!restored.jwt,
|
|
470
|
+
savedAt: restored.timestamp,
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
|
|
450
474
|
this.setupMiddleware();
|
|
451
475
|
await this.setupRoutes();
|
|
452
476
|
this.setupWebSocket();
|
|
@@ -462,7 +486,7 @@ class WebServer {
|
|
|
462
486
|
// In remote session mode, auto-configure API key from environment
|
|
463
487
|
if (process.env.LOXIA_REMOTE_SESSION === 'true' && process.env.LOXIA_API_KEY && this.apiKeyManager) {
|
|
464
488
|
try {
|
|
465
|
-
await this.apiKeyManager.
|
|
489
|
+
await this.apiKeyManager.setSessionKeys(null, { loxiaApiKey: process.env.LOXIA_API_KEY });
|
|
466
490
|
this.logger.info('Remote session: API key auto-configured from environment');
|
|
467
491
|
} catch (err) {
|
|
468
492
|
this.logger.warn('Remote session: Failed to set API key from environment', { error: err.message });
|
|
@@ -485,6 +509,22 @@ class WebServer {
|
|
|
485
509
|
}
|
|
486
510
|
}
|
|
487
511
|
|
|
512
|
+
/**
|
|
513
|
+
* Single mutator for `lastAuthResult`. Always writes to disk so a
|
|
514
|
+
* server restart can restore the JWT. Passing null clears both
|
|
515
|
+
* memory and disk. Every call site that previously assigned to
|
|
516
|
+
* `this.lastAuthResult` directly should go through this helper.
|
|
517
|
+
* @param {Object|null} value
|
|
518
|
+
* @returns {Promise<void>}
|
|
519
|
+
*/
|
|
520
|
+
async _setLastAuthResult(value) {
|
|
521
|
+
this.lastAuthResult = value || null;
|
|
522
|
+
// Fire-and-forget would be tempting but it lets a fast-following
|
|
523
|
+
// /api/auth/status read race the write. Awaiting is cheap: one
|
|
524
|
+
// ~200B AES-GCM write to a local file.
|
|
525
|
+
await this.authCacheStore.save(this.lastAuthResult);
|
|
526
|
+
}
|
|
527
|
+
|
|
488
528
|
/**
|
|
489
529
|
* Start the Visual Editor Server (always-on mode)
|
|
490
530
|
* Server runs on port 4000 (or configured port) and waits for agent connections
|
|
@@ -859,7 +899,7 @@ class WebServer {
|
|
|
859
899
|
|
|
860
900
|
// Store the API key if generated
|
|
861
901
|
if (apiKey && this.apiKeyManager) {
|
|
862
|
-
await this.apiKeyManager.
|
|
902
|
+
await this.apiKeyManager.setSessionKeys(null, { loxiaApiKey: apiKey });
|
|
863
903
|
this.logger?.info('API key auto-configured from OAuth login', { userId: userInfo.id });
|
|
864
904
|
}
|
|
865
905
|
|
|
@@ -870,11 +910,11 @@ class WebServer {
|
|
|
870
910
|
// marketplace publish/install/rate calls would 401 because the
|
|
871
911
|
// FE never got the token into localStorage. Logic lives in
|
|
872
912
|
// `utilities/authCache.js` so unit tests can lock the contract.
|
|
873
|
-
this.
|
|
913
|
+
await this._setLastAuthResult(recordOAuthResult({
|
|
874
914
|
user: userInfo,
|
|
875
915
|
jwt: token,
|
|
876
916
|
hasApiKey: !!apiKey,
|
|
877
|
-
});
|
|
917
|
+
}));
|
|
878
918
|
|
|
879
919
|
// Broadcast auth success to connected web UI clients
|
|
880
920
|
// Include the raw JWT so the frontend can use it for marketplace API calls
|
|
@@ -921,7 +961,17 @@ h2{color:#16a34a;margin-bottom:.5rem;} p{color:#666;}</style></head>
|
|
|
921
961
|
});
|
|
922
962
|
|
|
923
963
|
// Auth resolve — resolve user account from an existing API key by calling the remote backend
|
|
924
|
-
// This enables "API key → account auto-link" without requiring a full OAuth login
|
|
964
|
+
// This enables "API key → account auto-link" without requiring a full OAuth login.
|
|
965
|
+
//
|
|
966
|
+
// Preferred path: POST /auth/mint-jwt-from-apikey, which returns
|
|
967
|
+
// {token, user} in one round-trip. We cache the JWT so subsequent
|
|
968
|
+
// /api/account/* calls (which require a JWT, not an API key) work
|
|
969
|
+
// without forcing the user through OAuth.
|
|
970
|
+
//
|
|
971
|
+
// Fallback path: GET /auth/me — used when the backend predates
|
|
972
|
+
// the mint endpoint (older deployment). User is still cached but
|
|
973
|
+
// no JWT is minted; /api/account/* will be unavailable until the
|
|
974
|
+
// user does a real OAuth login.
|
|
925
975
|
this.app.get('/api/auth/resolve', async (req, res) => {
|
|
926
976
|
try {
|
|
927
977
|
const loxiaApiKey = this.apiKeyManager?.getKeysForRequest?.(null, { platformProvided: true })?.loxiaApiKey;
|
|
@@ -930,6 +980,34 @@ h2{color:#16a34a;margin-bottom:.5rem;} p{color:#666;}</style></head>
|
|
|
930
980
|
}
|
|
931
981
|
|
|
932
982
|
const backendBaseUrl = this.config?.backend?.baseUrl || 'https://autopilot-api.azurewebsites.net';
|
|
983
|
+
|
|
984
|
+
// Preferred: mint a session JWT alongside the user lookup.
|
|
985
|
+
try {
|
|
986
|
+
const mintResp = await fetch(`${backendBaseUrl}/auth/mint-jwt-from-apikey`, {
|
|
987
|
+
method: 'POST',
|
|
988
|
+
headers: { 'Authorization': `Bearer ${loxiaApiKey}` },
|
|
989
|
+
});
|
|
990
|
+
if (mintResp.ok) {
|
|
991
|
+
const data = await mintResp.json();
|
|
992
|
+
const user = data.user;
|
|
993
|
+
const jwt = data.token;
|
|
994
|
+
if (user && jwt) {
|
|
995
|
+
await this._setLastAuthResult(recordOAuthResult({
|
|
996
|
+
user,
|
|
997
|
+
jwt,
|
|
998
|
+
hasApiKey: true,
|
|
999
|
+
}));
|
|
1000
|
+
return res.json({ success: true, user, mintedJwt: true });
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
// 404 from older backends → fall through to /auth/me; other
|
|
1004
|
+
// non-2xx → also fall through (the user record is still
|
|
1005
|
+
// worth caching even if we couldn't mint a JWT).
|
|
1006
|
+
} catch (mintErr) {
|
|
1007
|
+
this.logger?.warn('mint-jwt-from-apikey failed; falling back to /auth/me', { error: mintErr.message });
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
// Fallback: just identify the user, no JWT.
|
|
933
1011
|
const response = await fetch(`${backendBaseUrl}/auth/me`, {
|
|
934
1012
|
headers: { 'Authorization': `Bearer ${loxiaApiKey}` }
|
|
935
1013
|
});
|
|
@@ -942,15 +1020,13 @@ h2{color:#16a34a;margin-bottom:.5rem;} p{color:#666;}</style></head>
|
|
|
942
1020
|
const user = data.user || data;
|
|
943
1021
|
|
|
944
1022
|
// Cache the resolved user for subsequent /api/auth/status calls.
|
|
945
|
-
// Preserves any JWT from a prior OAuth login
|
|
946
|
-
|
|
947
|
-
// API key). See utilities/authCache.js for the invariant.
|
|
948
|
-
this.lastAuthResult = recordResolvedUser({
|
|
1023
|
+
// Preserves any JWT from a prior OAuth login.
|
|
1024
|
+
await this._setLastAuthResult(recordResolvedUser({
|
|
949
1025
|
user,
|
|
950
1026
|
prevCache: this.lastAuthResult,
|
|
951
|
-
});
|
|
1027
|
+
}));
|
|
952
1028
|
|
|
953
|
-
res.json({ success: true, user });
|
|
1029
|
+
res.json({ success: true, user, mintedJwt: false });
|
|
954
1030
|
} catch (error) {
|
|
955
1031
|
this.logger?.warn('Failed to resolve user from API key', { error: error.message });
|
|
956
1032
|
res.json({ success: true, user: null, reason: 'fetch_error', error: error.message });
|
|
@@ -961,9 +1037,9 @@ h2{color:#16a34a;margin-bottom:.5rem;} p{color:#666;}</style></head>
|
|
|
961
1037
|
this.app.post('/api/auth/signout', async (req, res) => {
|
|
962
1038
|
try {
|
|
963
1039
|
if (this.apiKeyManager) {
|
|
964
|
-
await this.apiKeyManager.
|
|
1040
|
+
await this.apiKeyManager.removeSessionKeys(null);
|
|
965
1041
|
}
|
|
966
|
-
this.
|
|
1042
|
+
await this._setLastAuthResult(null);
|
|
967
1043
|
this.broadcastToSession(null, {
|
|
968
1044
|
type: 'auth_signout',
|
|
969
1045
|
data: { timestamp: new Date().toISOString() }
|
|
@@ -974,6 +1050,19 @@ h2{color:#16a34a;margin-bottom:.5rem;} p{color:#666;}</style></head>
|
|
|
974
1050
|
}
|
|
975
1051
|
});
|
|
976
1052
|
|
|
1053
|
+
// =====================================================
|
|
1054
|
+
// Account & API-key management (proxied to autopilot-backend).
|
|
1055
|
+
// Defined in `interfaces/accountRoutes.js`; mounted here so the FE
|
|
1056
|
+
// can hit /api/account/{profile,balance,keys,handoff} without ever
|
|
1057
|
+
// touching the user's JWT directly.
|
|
1058
|
+
// =====================================================
|
|
1059
|
+
this.app.use('/api/account', createAccountRouter({
|
|
1060
|
+
getJwt: () => this.lastAuthResult?.jwt || null,
|
|
1061
|
+
getBrand: () => getBrand().isOnBuzz ? 'onbuzz' : 'autopilot',
|
|
1062
|
+
backendBaseUrl: this.config?.backend?.baseUrl,
|
|
1063
|
+
logger: this.logger,
|
|
1064
|
+
}));
|
|
1065
|
+
|
|
977
1066
|
// =====================================================
|
|
978
1067
|
// System Update API
|
|
979
1068
|
// =====================================================
|
|
@@ -85,12 +85,10 @@ describe('ApiKeyManager', () => {
|
|
|
85
85
|
expect(logger.warn).toHaveBeenCalled();
|
|
86
86
|
});
|
|
87
87
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
expect(id).toContain('loxia-api-key-encryption-v1');
|
|
93
|
-
});
|
|
88
|
+
// _getMachineIdentifier moved to `utilities/secretsCipher.js` as part
|
|
89
|
+
// of the DRY refactor sharing the cipher with `services/authCacheStore.js`.
|
|
90
|
+
// The equivalent coverage now lives in
|
|
91
|
+
// `src/utilities/__tests__/secretsCipher.test.js`.
|
|
94
92
|
|
|
95
93
|
test('_encrypt throws when no encryption key', () => {
|
|
96
94
|
expect(() => manager._encrypt('test')).toThrow('Encryption key not initialized');
|