mbkauthe 4.8.3 → 4.9.0

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.
@@ -0,0 +1 @@
1
+ <svg id="my-svg" width="100%" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="max-width: 928px; background-color: white;" viewBox="-50 -10 928 2389" role="graphics-document document" aria-roledescription="sequence"><rect x="34" y="1068" fill="rgb(245, 245, 245)" width="764" height="1215" class="rect"/><rect x="44" y="1695" fill="rgb(220, 230, 250)" width="744" height="578" class="rect"/><rect x="44" y="1181" fill="rgb(240, 240, 240)" width="744" height="504" class="rect"/><rect x="40" y="75" fill="rgb(235, 245, 255)" width="748" height="983" class="rect"/><g><rect x="678" y="2303" fill="#eaeaea" stroke="#666" width="150" height="65" name="DB" rx="3" ry="3" class="actor actor-bottom"/><text x="753" y="2335.5" dominant-baseline="central" alignment-baseline="central" class="actor actor-box" style="text-anchor: middle; font-size: 16px; font-weight: 400;"><tspan x="753" dy="0">Database</tspan></text></g><g><rect x="339" y="2303" fill="#eaeaea" stroke="#666" width="150" height="65" name="S" rx="3" ry="3" class="actor actor-bottom"/><text x="414" y="2335.5" dominant-baseline="central" alignment-baseline="central" class="actor actor-box" style="text-anchor: middle; font-size: 16px; font-weight: 400;"><tspan x="414" dy="0">Server</tspan></text></g><g><rect x="0" y="2303" fill="#eaeaea" stroke="#666" width="150" height="65" name="C" rx="3" ry="3" class="actor actor-bottom"/><text x="75" y="2335.5" dominant-baseline="central" alignment-baseline="central" class="actor actor-box" style="text-anchor: middle; font-size: 16px; font-weight: 400;"><tspan x="75" dy="0">Client</tspan></text></g><g><line id="actor2" x1="753" y1="65" x2="753" y2="2303" class="actor-line 200" stroke-width="0.5px" stroke="#999" name="DB" data-et="life-line" data-id="DB"/><g id="root-2" data-et="participant" data-type="participant" data-id="DB"><rect x="678" y="0" fill="#eaeaea" stroke="#666" width="150" height="65" name="DB" rx="3" ry="3" class="actor actor-top"/><text x="753" y="32.5" dominant-baseline="central" alignment-baseline="central" class="actor actor-box" style="text-anchor: middle; font-size: 16px; font-weight: 400;"><tspan x="753" dy="0">Database</tspan></text></g></g><g><line id="actor1" x1="414" y1="65" x2="414" y2="2303" class="actor-line 200" stroke-width="0.5px" stroke="#999" name="S" data-et="life-line" data-id="S"/><g id="root-1" data-et="participant" data-type="participant" data-id="S"><rect x="339" y="0" fill="#eaeaea" stroke="#666" width="150" height="65" name="S" rx="3" ry="3" class="actor actor-top"/><text x="414" y="32.5" dominant-baseline="central" alignment-baseline="central" class="actor actor-box" style="text-anchor: middle; font-size: 16px; font-weight: 400;"><tspan x="414" dy="0">Server</tspan></text></g></g><g><line id="actor0" x1="75" y1="65" x2="75" y2="2303" class="actor-line 200" stroke-width="0.5px" stroke="#999" name="C" data-et="life-line" data-id="C"/><g id="root-0" data-et="participant" data-type="participant" data-id="C"><rect x="0" y="0" fill="#eaeaea" stroke="#666" width="150" height="65" name="C" rx="3" ry="3" class="actor actor-top"/><text x="75" y="32.5" dominant-baseline="central" alignment-baseline="central" class="actor actor-box" style="text-anchor: middle; font-size: 16px; font-weight: 400;"><tspan x="75" dy="0">Client</tspan></text></g></g><style>#my-svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#my-svg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#my-svg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#my-svg .error-icon{fill:#552222;}#my-svg .error-text{fill:#552222;stroke:#552222;}#my-svg .edge-thickness-normal{stroke-width:1px;}#my-svg .edge-thickness-thick{stroke-width:3.5px;}#my-svg .edge-pattern-solid{stroke-dasharray:0;}#my-svg .edge-thickness-invisible{stroke-width:0;fill:none;}#my-svg .edge-pattern-dashed{stroke-dasharray:3;}#my-svg .edge-pattern-dotted{stroke-dasharray:2;}#my-svg .marker{fill:#333333;stroke:#333333;}#my-svg .marker.cross{stroke:#333333;}#my-svg svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#my-svg p{margin:0;}#my-svg .actor{stroke:#9370DB;fill:#ECECFF;stroke-width:1;}#my-svg rect.actor.outer-path[data-look="neo"]{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#my-svg rect.note[data-look="neo"]{stroke:#aaaa33;fill:#fff5ad;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#my-svg text.actor&gt;tspan{fill:black;stroke:none;}#my-svg .actor-line{stroke:#9370DB;}#my-svg .innerArc{stroke-width:1.5;stroke-dasharray:none;}#my-svg .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#my-svg .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#my-svg [id$="-arrowhead"] path{fill:#333;stroke:#333;}#my-svg .sequenceNumber{fill:white;}#my-svg [id$="-sequencenumber"]{fill:#333;}#my-svg [id$="-crosshead"] path{fill:#333;stroke:#333;}#my-svg .messageText{fill:#333;stroke:none;}#my-svg .labelBox{stroke:#9370DB;fill:#ECECFF;filter:none;}#my-svg .labelText,#my-svg .labelText&gt;tspan{fill:black;stroke:none;}#my-svg .loopText,#my-svg .loopText&gt;tspan{fill:black;stroke:none;}#my-svg .sectionTitle,#my-svg .sectionTitle&gt;tspan{fill:black;stroke:none;}#my-svg .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:#9370DB;fill:#9370DB;}#my-svg .note{stroke:#aaaa33;fill:#fff5ad;}#my-svg .noteText,#my-svg .noteText&gt;tspan{fill:black;stroke:none;font-weight:normal;}#my-svg .activation0{fill:#f4f4f4;stroke:#666;}#my-svg .activation1{fill:#f4f4f4;stroke:#666;}#my-svg .activation2{fill:#f4f4f4;stroke:#666;}#my-svg .actorPopupMenu{position:absolute;}#my-svg .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#my-svg .actor-man circle,#my-svg line{fill:#ECECFF;stroke-width:2px;}#my-svg g rect.rect{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));stroke:#9370DB;}#my-svg .node .neo-node{stroke:#9370DB;}#my-svg [data-look="neo"].node rect,#my-svg [data-look="neo"].cluster rect,#my-svg [data-look="neo"].node polygon{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#my-svg [data-look="neo"].node path{stroke:#9370DB;stroke-width:1px;}#my-svg [data-look="neo"].node .outer-path{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#my-svg [data-look="neo"].node .neo-line path{stroke:#9370DB;filter:none;}#my-svg [data-look="neo"].node circle{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#my-svg [data-look="neo"].node circle .state-start{fill:#000000;}#my-svg [data-look="neo"].icon-shape .icon{fill:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#my-svg [data-look="neo"].icon-shape .icon-neo path{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#my-svg :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}</style><g/><defs><symbol id="my-svg-computer" width="24" height="24"><path transform="scale(.5)" d="M2 2v13h20v-13h-20zm18 11h-16v-9h16v9zm-10.228 6l.466-1h3.524l.467 1h-4.457zm14.228 3h-24l2-6h2.104l-1.33 4h18.45l-1.297-4h2.073l2 6zm-5-10h-14v-7h14v7z"/></symbol></defs><defs><symbol id="my-svg-database" fill-rule="evenodd" clip-rule="evenodd"><path transform="scale(.5)" d="M12.258.001l.256.004.255.005.253.008.251.01.249.012.247.015.246.016.242.019.241.02.239.023.236.024.233.027.231.028.229.031.225.032.223.034.22.036.217.038.214.04.211.041.208.043.205.045.201.046.198.048.194.05.191.051.187.053.183.054.18.056.175.057.172.059.168.06.163.061.16.063.155.064.15.066.074.033.073.033.071.034.07.034.069.035.068.035.067.035.066.035.064.036.064.036.062.036.06.036.06.037.058.037.058.037.055.038.055.038.053.038.052.038.051.039.05.039.048.039.047.039.045.04.044.04.043.04.041.04.04.041.039.041.037.041.036.041.034.041.033.042.032.042.03.042.029.042.027.042.026.043.024.043.023.043.021.043.02.043.018.044.017.043.015.044.013.044.012.044.011.045.009.044.007.045.006.045.004.045.002.045.001.045v17l-.001.045-.002.045-.004.045-.006.045-.007.045-.009.044-.011.045-.012.044-.013.044-.015.044-.017.043-.018.044-.02.043-.021.043-.023.043-.024.043-.026.043-.027.042-.029.042-.03.042-.032.042-.033.042-.034.041-.036.041-.037.041-.039.041-.04.041-.041.04-.043.04-.044.04-.045.04-.047.039-.048.039-.05.039-.051.039-.052.038-.053.038-.055.038-.055.038-.058.037-.058.037-.06.037-.06.036-.062.036-.064.036-.064.036-.066.035-.067.035-.068.035-.069.035-.07.034-.071.034-.073.033-.074.033-.15.066-.155.064-.16.063-.163.061-.168.06-.172.059-.175.057-.18.056-.183.054-.187.053-.191.051-.194.05-.198.048-.201.046-.205.045-.208.043-.211.041-.214.04-.217.038-.22.036-.223.034-.225.032-.229.031-.231.028-.233.027-.236.024-.239.023-.241.02-.242.019-.246.016-.247.015-.249.012-.251.01-.253.008-.255.005-.256.004-.258.001-.258-.001-.256-.004-.255-.005-.253-.008-.251-.01-.249-.012-.247-.015-.245-.016-.243-.019-.241-.02-.238-.023-.236-.024-.234-.027-.231-.028-.228-.031-.226-.032-.223-.034-.22-.036-.217-.038-.214-.04-.211-.041-.208-.043-.204-.045-.201-.046-.198-.048-.195-.05-.19-.051-.187-.053-.184-.054-.179-.056-.176-.057-.172-.059-.167-.06-.164-.061-.159-.063-.155-.064-.151-.066-.074-.033-.072-.033-.072-.034-.07-.034-.069-.035-.068-.035-.067-.035-.066-.035-.064-.036-.063-.036-.062-.036-.061-.036-.06-.037-.058-.037-.057-.037-.056-.038-.055-.038-.053-.038-.052-.038-.051-.039-.049-.039-.049-.039-.046-.039-.046-.04-.044-.04-.043-.04-.041-.04-.04-.041-.039-.041-.037-.041-.036-.041-.034-.041-.033-.042-.032-.042-.03-.042-.029-.042-.027-.042-.026-.043-.024-.043-.023-.043-.021-.043-.02-.043-.018-.044-.017-.043-.015-.044-.013-.044-.012-.044-.011-.045-.009-.044-.007-.045-.006-.045-.004-.045-.002-.045-.001-.045v-17l.001-.045.002-.045.004-.045.006-.045.007-.045.009-.044.011-.045.012-.044.013-.044.015-.044.017-.043.018-.044.02-.043.021-.043.023-.043.024-.043.026-.043.027-.042.029-.042.03-.042.032-.042.033-.042.034-.041.036-.041.037-.041.039-.041.04-.041.041-.04.043-.04.044-.04.046-.04.046-.039.049-.039.049-.039.051-.039.052-.038.053-.038.055-.038.056-.038.057-.037.058-.037.06-.037.061-.036.062-.036.063-.036.064-.036.066-.035.067-.035.068-.035.069-.035.07-.034.072-.034.072-.033.074-.033.151-.066.155-.064.159-.063.164-.061.167-.06.172-.059.176-.057.179-.056.184-.054.187-.053.19-.051.195-.05.198-.048.201-.046.204-.045.208-.043.211-.041.214-.04.217-.038.22-.036.223-.034.226-.032.228-.031.231-.028.234-.027.236-.024.238-.023.241-.02.243-.019.245-.016.247-.015.249-.012.251-.01.253-.008.255-.005.256-.004.258-.001.258.001zm-9.258 20.499v.01l.001.021.003.021.004.022.005.021.006.022.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.023.018.024.019.024.021.024.022.025.023.024.024.025.052.049.056.05.061.051.066.051.07.051.075.051.079.052.084.052.088.052.092.052.097.052.102.051.105.052.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.048.144.049.147.047.152.047.155.047.16.045.163.045.167.043.171.043.176.041.178.041.183.039.187.039.19.037.194.035.197.035.202.033.204.031.209.03.212.029.216.027.219.025.222.024.226.021.23.02.233.018.236.016.24.015.243.012.246.01.249.008.253.005.256.004.259.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.021.224-.024.22-.026.216-.027.212-.028.21-.031.205-.031.202-.034.198-.034.194-.036.191-.037.187-.039.183-.04.179-.04.175-.042.172-.043.168-.044.163-.045.16-.046.155-.046.152-.047.148-.048.143-.049.139-.049.136-.05.131-.05.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.053.083-.051.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.05.023-.024.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.023.01-.022.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.127l-.077.055-.08.053-.083.054-.085.053-.087.052-.09.052-.093.051-.095.05-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.045-.118.044-.12.043-.122.042-.124.042-.126.041-.128.04-.13.04-.132.038-.134.038-.135.037-.138.037-.139.035-.142.035-.143.034-.144.033-.147.032-.148.031-.15.03-.151.03-.153.029-.154.027-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.01-.179.008-.179.008-.181.006-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.006-.179-.008-.179-.008-.178-.01-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.027-.153-.029-.151-.03-.15-.03-.148-.031-.146-.032-.145-.033-.143-.034-.141-.035-.14-.035-.137-.037-.136-.037-.134-.038-.132-.038-.13-.04-.128-.04-.126-.041-.124-.042-.122-.042-.12-.044-.117-.043-.116-.045-.113-.045-.112-.046-.109-.047-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.05-.093-.052-.09-.051-.087-.052-.085-.053-.083-.054-.08-.054-.077-.054v4.127zm0-5.654v.011l.001.021.003.021.004.021.005.022.006.022.007.022.009.022.01.022.011.023.012.023.013.023.015.024.016.023.017.024.018.024.019.024.021.024.022.024.023.025.024.024.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.052.11.051.114.051.119.052.123.05.127.051.131.05.135.049.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.044.171.042.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.022.23.02.233.018.236.016.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.012.241-.015.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.048.139-.05.136-.049.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.051.051-.049.023-.025.023-.024.021-.025.02-.024.019-.024.018-.024.017-.024.015-.023.014-.023.013-.024.012-.022.01-.023.01-.023.008-.022.006-.022.006-.022.004-.021.004-.022.001-.021.001-.021v-4.139l-.077.054-.08.054-.083.054-.085.052-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.044-.118.044-.12.044-.122.042-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.035-.143.033-.144.033-.147.033-.148.031-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.009-.179.009-.179.007-.181.007-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.007-.179-.007-.179-.009-.178-.009-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.031-.146-.033-.145-.033-.143-.033-.141-.035-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.04-.126-.041-.124-.042-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.051-.093-.051-.09-.051-.087-.053-.085-.052-.083-.054-.08-.054-.077-.054v4.139zm0-5.666v.011l.001.02.003.022.004.021.005.022.006.021.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.024.018.023.019.024.021.025.022.024.023.024.024.025.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.051.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.043.171.043.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.021.23.02.233.018.236.017.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.013.241-.014.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.049.139-.049.136-.049.131-.051.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.049.023-.025.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.022.01-.023.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.153l-.077.054-.08.054-.083.053-.085.053-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.048-.105.048-.106.048-.109.046-.111.046-.114.046-.115.044-.118.044-.12.043-.122.043-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.034-.143.034-.144.033-.147.032-.148.032-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.024-.161.024-.162.023-.163.023-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.01-.178.01-.179.009-.179.007-.181.006-.182.006-.182.004-.184.003-.184.001-.185.001-.185-.001-.184-.001-.184-.003-.182-.004-.182-.006-.181-.006-.179-.007-.179-.009-.178-.01-.176-.01-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.023-.162-.023-.161-.024-.159-.024-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.032-.146-.032-.145-.033-.143-.034-.141-.034-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.041-.126-.041-.124-.041-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.048-.105-.048-.102-.048-.1-.05-.097-.049-.095-.051-.093-.051-.09-.052-.087-.052-.085-.053-.083-.053-.08-.054-.077-.054v4.153zm8.74-8.179l-.257.004-.254.005-.25.008-.247.011-.244.012-.241.014-.237.016-.233.018-.231.021-.226.022-.224.023-.22.026-.216.027-.212.028-.21.031-.205.032-.202.033-.198.034-.194.036-.191.038-.187.038-.183.04-.179.041-.175.042-.172.043-.168.043-.163.045-.16.046-.155.046-.152.048-.148.048-.143.048-.139.049-.136.05-.131.05-.126.051-.123.051-.118.051-.114.052-.11.052-.106.052-.101.052-.096.052-.092.052-.088.052-.083.052-.079.052-.074.051-.07.052-.065.051-.06.05-.056.05-.051.05-.023.025-.023.024-.021.024-.02.025-.019.024-.018.024-.017.023-.015.024-.014.023-.013.023-.012.023-.01.023-.01.022-.008.022-.006.023-.006.021-.004.022-.004.021-.001.021-.001.021.001.021.001.021.004.021.004.022.006.021.006.023.008.022.01.022.01.023.012.023.013.023.014.023.015.024.017.023.018.024.019.024.02.025.021.024.023.024.023.025.051.05.056.05.06.05.065.051.07.052.074.051.079.052.083.052.088.052.092.052.096.052.101.052.106.052.11.052.114.052.118.051.123.051.126.051.131.05.136.05.139.049.143.048.148.048.152.048.155.046.16.046.163.045.168.043.172.043.175.042.179.041.183.04.187.038.191.038.194.036.198.034.202.033.205.032.21.031.212.028.216.027.22.026.224.023.226.022.231.021.233.018.237.016.241.014.244.012.247.011.25.008.254.005.257.004.26.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.022.224-.023.22-.026.216-.027.212-.028.21-.031.205-.032.202-.033.198-.034.194-.036.191-.038.187-.038.183-.04.179-.041.175-.042.172-.043.168-.043.163-.045.16-.046.155-.046.152-.048.148-.048.143-.048.139-.049.136-.05.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.05.051-.05.023-.025.023-.024.021-.024.02-.025.019-.024.018-.024.017-.023.015-.024.014-.023.013-.023.012-.023.01-.023.01-.022.008-.022.006-.023.006-.021.004-.022.004-.021.001-.021.001-.021-.001-.021-.001-.021-.004-.021-.004-.022-.006-.021-.006-.023-.008-.022-.01-.022-.01-.023-.012-.023-.013-.023-.014-.023-.015-.024-.017-.023-.018-.024-.019-.024-.02-.025-.021-.024-.023-.024-.023-.025-.051-.05-.056-.05-.06-.05-.065-.051-.07-.052-.074-.051-.079-.052-.083-.052-.088-.052-.092-.052-.096-.052-.101-.052-.106-.052-.11-.052-.114-.052-.118-.051-.123-.051-.126-.051-.131-.05-.136-.05-.139-.049-.143-.048-.148-.048-.152-.048-.155-.046-.16-.046-.163-.045-.168-.043-.172-.043-.175-.042-.179-.041-.183-.04-.187-.038-.191-.038-.194-.036-.198-.034-.202-.033-.205-.032-.21-.031-.212-.028-.216-.027-.22-.026-.224-.023-.226-.022-.231-.021-.233-.018-.237-.016-.241-.014-.244-.012-.247-.011-.25-.008-.254-.005-.257-.004-.26-.001-.26.001z"/></symbol></defs><defs><symbol id="my-svg-clock" width="24" height="24"><path transform="scale(.5)" d="M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.848 12.459c.202.038.202.333.001.372-1.907.361-6.045 1.111-6.547 1.111-.719 0-1.301-.582-1.301-1.301 0-.512.77-5.447 1.125-7.445.034-.192.312-.181.343.014l.985 6.238 5.394 1.011z"/></symbol></defs><defs><marker id="my-svg-arrowhead" refX="7.9" refY="5" markerUnits="userSpaceOnUse" markerWidth="12" markerHeight="12" orient="auto-start-reverse"><path d="M -1 0 L 10 5 L 0 10 z"/></marker></defs><defs><marker id="my-svg-crosshead" markerWidth="15" markerHeight="8" orient="auto" refX="4" refY="4.5"><path fill="none" stroke="#000000" stroke-width="1pt" d="M 1,2 L 6,7 M 6,2 L 1,7" style="stroke-dasharray: 0, 0;"/></marker></defs><defs><marker id="my-svg-filled-head" refX="15.5" refY="7" markerWidth="20" markerHeight="28" orient="auto"><path d="M 18,7 L9,13 L14,7 L9,1 Z"/></marker></defs><defs><marker id="my-svg-sequencenumber" refX="15" refY="15" markerWidth="60" markerHeight="40" orient="auto"><circle cx="15" cy="15" r="6"/></marker></defs><defs><marker id="my-svg-solidTopArrowHead" refX="7.9" refY="7.25" markerUnits="userSpaceOnUse" markerWidth="12" markerHeight="12" orient="auto-start-reverse"><path d="M 0 0 L 10 8 L 0 8 z"/></marker></defs><defs><marker id="my-svg-solidBottomArrowHead" refX="7.9" refY="0.75" markerUnits="userSpaceOnUse" markerWidth="12" markerHeight="12" orient="auto-start-reverse"><path d="M 0 0 L 10 0 L 0 8 z"/></marker></defs><defs><marker id="my-svg-stickTopArrowHead" refX="7.5" refY="7" markerUnits="userSpaceOnUse" markerWidth="12" markerHeight="12" orient="auto-start-reverse"><path d="M 0 0 L 7 7" stroke="black" stroke-width="1.5" fill="none"/></marker></defs><defs><marker id="my-svg-stickBottomArrowHead" refX="7.5" refY="0" markerUnits="userSpaceOnUse" markerWidth="12" markerHeight="12" orient="auto-start-reverse"><path d="M 0 7 L 7 0" stroke="black" stroke-width="1.5" fill="none"/></marker></defs><g data-et="note" data-id="i1"><rect x="50" y="95" fill="#EDF2AE" stroke="#666" width="728" height="39" class="note"/><text x="414" y="100" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="noteText" dy="1em" style="font-size: 16px; font-weight: 400;"><tspan x="414">Authentication Flow</tspan></text></g><g data-et="control-structure" data-id="i13"><line x1="64" y1="424" x2="764" y2="424" class="loopLine"/><line x1="764" y1="424" x2="764" y2="749" class="loopLine"/><line x1="64" y1="749" x2="764" y2="749" class="loopLine"/><line x1="64" y1="424" x2="64" y2="749" class="loopLine"/><polygon points="64,424 114,424 114,437 105.6,444 64,444" class="labelBox"/><text x="89" y="437" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="labelText" style="font-size: 16px; font-weight: 400;">alt</text><text x="439" y="442" text-anchor="middle" class="loopText" style="font-size: 16px; font-weight: 400;"><tspan x="439">[2FA Enabled &amp; Device Not Trusted]</tspan></text></g><g data-et="note" data-id="i14"><rect x="389" y="759" fill="#EDF2AE" stroke="#666" width="389" height="39" class="note"/><text x="584" y="764" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="noteText" dy="1em" style="font-size: 16px; font-weight: 400;"><tspan x="584">completeLoginProcess</tspan></text></g><g data-et="note" data-id="i22"><rect x="50" y="1088" fill="#EDF2AE" stroke="#666" width="728" height="39" class="note"/><text x="414" y="1093" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="noteText" dy="1em" style="font-size: 16px; font-weight: 400;"><tspan x="414">Request Authentication Middleware Flow</tspan></text></g><g data-et="note" data-id="i25"><rect x="389" y="1201" fill="#EDF2AE" stroke="#666" width="389" height="39" class="note"/><text x="584" y="1206" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="noteText" dy="1em" style="font-size: 16px; font-weight: 400;"><tspan x="584">Token Path (API)</tspan></text></g><g data-et="control-structure" data-id="i34"><line x1="64" y1="1413" x2="764" y2="1413" class="loopLine"/><line x1="764" y1="1413" x2="764" y2="1665" class="loopLine"/><line x1="64" y1="1665" x2="764" y2="1665" class="loopLine"/><line x1="64" y1="1413" x2="64" y2="1665" class="loopLine"/><line x1="64" y1="1581" x2="764" y2="1581" class="loopLine" style="stroke-dasharray: 3, 3;"/><polygon points="64,1413 114,1413 114,1426 105.6,1433 64,1433" class="labelBox"/><text x="89" y="1426" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="labelText" style="font-size: 16px; font-weight: 400;">alt</text><text x="439" y="1431" text-anchor="middle" class="loopText" style="font-size: 16px; font-weight: 400;"><tspan x="439">[Valid &amp; Not Expired]</tspan></text><text x="414" y="1599" text-anchor="middle" class="sectionTitle" style="font-size: 16px; font-weight: 400;">[Invalid/Expired]</text></g><g data-et="control-structure" data-id="i35"><line x1="54" y1="1250" x2="774" y2="1250" class="loopLine"/><line x1="774" y1="1250" x2="774" y2="1675" class="loopLine"/><line x1="54" y1="1675" x2="774" y2="1675" class="loopLine"/><line x1="54" y1="1250" x2="54" y2="1675" class="loopLine"/><polygon points="54,1250 104,1250 104,1263 95.6,1270 54,1270" class="labelBox"/><text x="79" y="1263" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="labelText" style="font-size: 16px; font-weight: 400;">alt</text><text x="439" y="1268" text-anchor="middle" class="loopText" style="font-size: 16px; font-weight: 400;"><tspan x="439">[Header: Bearer mbk_token]</tspan></text></g><g data-et="note" data-id="i38"><rect x="389" y="1715" fill="#EDF2AE" stroke="#666" width="389" height="39" class="note"/><text x="584" y="1720" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="noteText" dy="1em" style="font-size: 16px; font-weight: 400;"><tspan x="584">Session Path (Web)</tspan></text></g><g data-et="control-structure" data-id="i48"><line x1="64" y1="1897" x2="543.5" y2="1897" class="loopLine"/><line x1="543.5" y1="1897" x2="543.5" y2="2253" class="loopLine"/><line x1="64" y1="2253" x2="543.5" y2="2253" class="loopLine"/><line x1="64" y1="1897" x2="64" y2="2253" class="loopLine"/><line x1="64" y1="2095" x2="543.5" y2="2095" class="loopLine" style="stroke-dasharray: 3, 3;"/><polygon points="64,1897 114,1897 114,1910 105.6,1917 64,1917" class="labelBox"/><text x="89" y="1910" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="labelText" style="font-size: 16px; font-weight: 400;">alt</text><text x="328.75" y="1915" text-anchor="middle" class="loopText" style="font-size: 16px; font-weight: 400;"><tspan x="328.75">[Session Valid &amp; User Active]</tspan></text><text x="303.75" y="2113" text-anchor="middle" class="sectionTitle" style="font-size: 16px; font-weight: 400;">[Session Expired/User Inactive]</text></g><g data-et="control-structure" data-id="i49"><line x1="54" y1="1764" x2="764" y2="1764" class="loopLine"/><line x1="764" y1="1764" x2="764" y2="2263" class="loopLine"/><line x1="54" y1="2263" x2="764" y2="2263" class="loopLine"/><line x1="54" y1="1764" x2="54" y2="2263" class="loopLine"/><polygon points="54,1764 104,1764 104,1777 95.6,1784 54,1784" class="labelBox"/><text x="79" y="1777" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="labelText" style="font-size: 16px; font-weight: 400;">alt</text><text x="434" y="1782" text-anchor="middle" class="loopText" style="font-size: 16px; font-weight: 400;"><tspan x="434">[Cookie: sessionId exists]</tspan></text></g><text x="243" y="149" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">POST /login (username, password)</text><line x1="76" y1="178" x2="410" y2="178" class="messageLine0" data-et="message" data-id="i2" data-from="C" data-to="S" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="fill: none;"/><text x="415" y="193" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">Validate payload format</text><path d="M 415,222 C 475,212 475,252 415,242" class="messageLine0" data-et="message" data-id="i3" data-from="S" data-to="S" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="fill: none;"/><text x="582" y="267" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">Query User &amp; 2FA status</text><line x1="415" y1="296" x2="749" y2="296" class="messageLine0" data-et="message" data-id="i4" data-from="S" data-to="DB" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="fill: none;"/><text x="585" y="311" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">User Data (Password Hash, 2FA Enabled)</text><line x1="752" y1="340" x2="418" y2="340" class="messageLine1" data-et="message" data-id="i5" data-from="DB" data-to="S" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="stroke-dasharray: 3, 3; fill: none;"/><text x="415" y="355" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">Compare Hash (PasswordEnc)</text><path d="M 415,384 C 475,374 475,414 415,404" class="messageLine0" data-et="message" data-id="i6" data-from="S" data-to="S" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="fill: none;"/><text x="246" y="474" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">200 (twoFactorRequired: true)</text><line x1="413" y1="503" x2="79" y2="503" class="messageLine1" data-et="message" data-id="i8" data-from="S" data-to="C" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="stroke-dasharray: 3, 3; fill: none;"/><text x="243" y="518" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">POST /verify-2fa (TOTP Token)</text><line x1="76" y1="547" x2="410" y2="547" class="messageLine0" data-et="message" data-id="i9" data-from="C" data-to="S" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="fill: none;"/><text x="582" y="562" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">Fetch TOTP Secret</text><line x1="415" y1="591" x2="749" y2="591" class="messageLine0" data-et="message" data-id="i10" data-from="S" data-to="DB" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="fill: none;"/><text x="585" y="606" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">Secret Key</text><line x1="752" y1="635" x2="418" y2="635" class="messageLine1" data-et="message" data-id="i11" data-from="DB" data-to="S" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="stroke-dasharray: 3, 3; fill: none;"/><text x="415" y="650" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">Verify TOTP</text><path d="M 415,679 C 475,669 475,709 415,699" class="messageLine0" data-et="message" data-id="i12" data-from="S" data-to="S" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="fill: none;"/><text x="582" y="813" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">Delete old sessions &amp; Prune max sessions</text><line x1="415" y1="842" x2="749" y2="842" class="messageLine0" data-et="message" data-id="i15" data-from="S" data-to="DB" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="fill: none;"/><text x="415" y="857" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">Regenerate Session ID</text><path d="M 415,886 C 475,876 475,916 415,906" class="messageLine0" data-et="message" data-id="i16" data-from="S" data-to="S" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="fill: none;"/><text x="582" y="931" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">Insert new Session row</text><line x1="415" y1="960" x2="749" y2="960" class="messageLine0" data-et="message" data-id="i17" data-from="S" data-to="DB" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="fill: none;"/><text x="582" y="975" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">Update Users.last_login</text><line x1="415" y1="1004" x2="749" y2="1004" class="messageLine0" data-et="message" data-id="i18" data-from="S" data-to="DB" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="fill: none;"/><text x="246" y="1019" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">200 Success (Set Encrypted Cookies)</text><line x1="413" y1="1048" x2="79" y2="1048" class="messageLine1" data-et="message" data-id="i19" data-from="S" data-to="C" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="stroke-dasharray: 3, 3; fill: none;"/><text x="243" y="1142" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">Request + Auth (Cookie or Bearer Token)</text><line x1="76" y1="1171" x2="410" y2="1171" class="messageLine0" data-et="message" data-id="i23" data-from="C" data-to="S" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="fill: none;"/><text x="415" y="1300" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">Hash Token</text><path d="M 415,1329 C 475,1319 475,1359 415,1349" class="messageLine0" data-et="message" data-id="i27" data-from="S" data-to="S" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="fill: none;"/><text x="582" y="1374" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">Query ApiTokens JOIN Users</text><line x1="415" y1="1403" x2="749" y2="1403" class="messageLine0" data-et="message" data-id="i28" data-from="S" data-to="DB" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="fill: none;"/><text x="582" y="1463" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">Update last_used</text><line x1="415" y1="1492" x2="749" y2="1492" class="messageLine0" data-et="message" data-id="i30" data-from="S" data-to="DB" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="fill: none;"/><text x="415" y="1507" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">Authorize Scope</text><path d="M 415,1536 C 475,1526 475,1566 415,1556" class="messageLine0" data-et="message" data-id="i31" data-from="S" data-to="S" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="fill: none;"/><text x="246" y="1626" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">401 Unauthorized</text><line x1="413" y1="1655" x2="79" y2="1655" class="messageLine1" data-et="message" data-id="i33" data-from="S" data-to="C" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="stroke-dasharray: 3, 3; fill: none;"/><text x="582" y="1814" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">Query Sessions JOIN Users</text><line x1="415" y1="1843" x2="749" y2="1843" class="messageLine0" data-et="message" data-id="i40" data-from="S" data-to="DB" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="fill: none;"/><text x="585" y="1858" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">Session Data + User Status</text><line x1="752" y1="1887" x2="418" y2="1887" class="messageLine1" data-et="message" data-id="i41" data-from="DB" data-to="S" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="stroke-dasharray: 3, 3; fill: none;"/><text x="415" y="1947" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">Sync Cookies &amp; Update session.user</text><path d="M 415,1976 C 475,1966 475,2006 415,1996" class="messageLine0" data-et="message" data-id="i43" data-from="S" data-to="S" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="fill: none;"/><text x="415" y="2021" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">Proceed to Route</text><path d="M 415,2050 C 475,2040 475,2080 415,2070" class="messageLine0" data-et="message" data-id="i44" data-from="S" data-to="S" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="fill: none;"/><text x="415" y="2140" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">Destroy Session &amp; Clear Cookies</text><path d="M 415,2169 C 475,2159 475,2199 415,2189" class="messageLine0" data-et="message" data-id="i46" data-from="S" data-to="S" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="fill: none;"/><text x="246" y="2214" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">403 Forbidden</text><line x1="413" y1="2243" x2="79" y2="2243" class="messageLine1" data-et="message" data-id="i47" data-from="S" data-to="C" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="stroke-dasharray: 3, 3; fill: none;"/></svg>
package/index.d.ts CHANGED
@@ -62,7 +62,7 @@ declare module 'mbkauthe' {
62
62
  GOOGLE_CLIENT_ID?: string;
63
63
  GOOGLE_CLIENT_SECRET?: string;
64
64
  loginRedirectURL?: string;
65
- EncPass?: 'true' | 'false' | 'f';
65
+ MAX_SESSIONS_PER_USER?: number;
66
66
  }
67
67
 
68
68
  export interface OAuthConfig {
@@ -100,7 +100,6 @@ declare module 'mbkauthe' {
100
100
  export interface DBUser {
101
101
  id: number;
102
102
  UserName: string;
103
- Password?: string;
104
103
  PasswordEnc?: string;
105
104
  Role: UserRole;
106
105
  Active: boolean;
package/index.js CHANGED
@@ -58,7 +58,7 @@ const renderDevError = (res, req, code, error, message, page, details) => render
58
58
  });
59
59
 
60
60
  if (isDevMode) {
61
- console.log("[mbkauthe] Dev mode is enabled. Starting server in dev mode.");
61
+ console.log(`[mbkauthe] Dev mode is enabled. Starting server in dev mode.`);
62
62
 
63
63
  app.get(["/dashboard", "/home", "/"], (req, res) => res.redirect("/mbkauthe/"));
64
64
 
@@ -98,5 +98,6 @@ export * from "./lib/routes/auth.js";
98
98
  export * from "./lib/utils/errors.js";
99
99
  export * from "./lib/config/cookies.js";
100
100
  export * from "./lib/config/security.js";
101
+ export * from "./lib/db/AuthRepository.js";
101
102
  export { mbkautheVar } from "#config.js";
102
103
  export default app;
@@ -33,7 +33,7 @@ const encryptCookiePayload = (data) => {
33
33
  data: encrypted
34
34
  };
35
35
  } catch (error) {
36
- console.error('[mbkauthe] Cookie encryption error:', error);
36
+ console.error(`[mbkauthe] Cookie encryption error:`, error);
37
37
  return null;
38
38
  }
39
39
  };
@@ -59,7 +59,7 @@ const decryptCookiePayload = (payload) => {
59
59
 
60
60
  return JSON.parse(decrypted);
61
61
  } catch (error) {
62
- console.error('[mbkauthe] Cookie decryption error:', error);
62
+ console.error(`[mbkauthe] Cookie decryption error:`, error);
63
63
  return null;
64
64
  }
65
65
  };
@@ -93,7 +93,7 @@ export const decryptSessionId = (encryptedSessionId) => {
93
93
  const decrypted = decryptCookiePayload(parsed);
94
94
  return decrypted?.sessionId || null;
95
95
  } catch (error) {
96
- console.error('[mbkauthe] SessionId decryption error:', error);
96
+ console.error(`[mbkauthe] SessionId decryption error:`, error);
97
97
  return null;
98
98
  }
99
99
  };
@@ -171,7 +171,7 @@ const parseAccountList = (raw, req) => {
171
171
  // Verify fingerprint matches current request
172
172
  const currentFingerprint = generateFingerprint(req);
173
173
  if (decrypted.fingerprint !== currentFingerprint) {
174
- console.warn('[mbkauthe] Cookie fingerprint mismatch - possible cookie theft attempt');
174
+ console.warn(`[mbkauthe] Cookie fingerprint mismatch - possible cookie theft attempt`);
175
175
  return [];
176
176
  }
177
177
 
@@ -190,7 +190,7 @@ const parseAccountList = (raw, req) => {
190
190
  .filter(item => item.sessionId && item.username)
191
191
  .slice(0, MAX_REMEMBERED_ACCOUNTS);
192
192
  } catch (error) {
193
- console.error('[mbkauthe] Error parsing account list:', error);
193
+ console.error(`[mbkauthe] Error parsing account list:`, error);
194
194
  return [];
195
195
  }
196
196
  };
@@ -215,7 +215,7 @@ const writeAccountList = (res, list, req) => {
215
215
  // Encrypt the payload
216
216
  const encrypted = encryptCookiePayload(payload);
217
217
  if (!encrypted) {
218
- console.error('[mbkauthe] Failed to encrypt account list cookie');
218
+ console.error(`[mbkauthe] Failed to encrypt account list cookie`);
219
219
  return;
220
220
  }
221
221
 
@@ -34,12 +34,12 @@ function validateConfiguration() {
34
34
  if (process.env.mbkauthShared) {
35
35
  mbkauthShared = JSON.parse(process.env.mbkauthShared);
36
36
  if (mbkauthShared && typeof mbkauthShared !== 'object') {
37
- console.warn('[mbkauthe] mbkauthShared is not a valid object, ignoring it');
37
+ console.warn(`[mbkauthe] mbkauthShared is not a valid object, ignoring it`);
38
38
  mbkauthShared = null;
39
39
  }
40
40
  }
41
41
  } catch (error) {
42
- console.warn('[mbkauthe] Invalid JSON in process.env.mbkauthShared, ignoring it');
42
+ console.warn(`[mbkauthe] Invalid JSON in process.env.mbkauthShared, ignoring it`);
43
43
  mbkauthShared = null;
44
44
  }
45
45
 
@@ -62,7 +62,7 @@ function validateConfiguration() {
62
62
 
63
63
  // Ensure specific keys are checked in mbkautheVar first, then mbkauthShared, then apply config defaults
64
64
  const keysToCheck = [
65
- "APP_NAME", "DEVICE_TRUST_DURATION_DAYS", "EncPass", "Main_SECRET_TOKEN", "SESSION_SECRET_KEY",
65
+ "APP_NAME", "DEVICE_TRUST_DURATION_DAYS", "Main_SECRET_TOKEN", "SESSION_SECRET_KEY",
66
66
  "IS_DEPLOYED", "LOGIN_DB", "MBKAUTH_TWO_FA_ENABLE", "COOKIE_EXPIRE_TIME", "DOMAIN", "loginRedirectURL",
67
67
  "GITHUB_LOGIN_ENABLED", "GITHUB_APP_SLUG", "GITHUB_APP_CLIENT_ID", "GITHUB_APP_CLIENT_SECRET", "GITHUB_CLIENT_ID", "GITHUB_CLIENT_SECRET", "GOOGLE_LOGIN_ENABLED", "GOOGLE_CLIENT_ID",
68
68
  "GOOGLE_CLIENT_SECRET", "MAX_SESSIONS_PER_USER"
@@ -70,7 +70,6 @@ function validateConfiguration() {
70
70
 
71
71
  const defaults = {
72
72
  DEVICE_TRUST_DURATION_DAYS: 7,
73
- EncPass: 'false',
74
73
  IS_DEPLOYED: 'false',
75
74
  MBKAUTH_TWO_FA_ENABLE: 'false',
76
75
  COOKIE_EXPIRE_TIME: 2,
@@ -95,7 +94,7 @@ function validateConfiguration() {
95
94
  });
96
95
 
97
96
  // Normalize boolean-like values to consistent lowercase 'true'/'false' strings
98
- ['GITHUB_LOGIN_ENABLED', 'GOOGLE_LOGIN_ENABLED', 'MBKAUTH_TWO_FA_ENABLE', 'IS_DEPLOYED', 'EncPass'].forEach(k => {
97
+ ['GITHUB_LOGIN_ENABLED', 'GOOGLE_LOGIN_ENABLED', 'MBKAUTH_TWO_FA_ENABLE', 'IS_DEPLOYED'].forEach(k => {
99
98
  const val = mbkautheVar[k];
100
99
  if (typeof val === 'boolean') {
101
100
  mbkautheVar[k] = val ? 'true' : 'false';
@@ -138,11 +137,6 @@ function validateConfiguration() {
138
137
  errors.push("mbkautheVar.GOOGLE_LOGIN_ENABLED must be either 'true' or 'false' or 'f'");
139
138
  }
140
139
 
141
- // Validate EncPass value if provided
142
- if (mbkautheVar.EncPass && !['true', 'false', 'f'].includes(mbkautheVar.EncPass.toLowerCase())) {
143
- errors.push("mbkautheVar.EncPass must be either 'true' or 'false' or 'f'");
144
- }
145
-
146
140
  // Validate GitHub login configuration
147
141
  if (mbkautheVar.GITHUB_LOGIN_ENABLED === "true") {
148
142
  const hasGithubClientId = !!(mbkautheVar.GITHUB_APP_CLIENT_ID || mbkautheVar.GITHUB_CLIENT_ID);
@@ -12,18 +12,18 @@ async function main() {
12
12
 
13
13
  try {
14
14
  const res = await dblogin.query(schemaSql);
15
- console.log("[mbkauthe] Schema applied successfully.");
15
+ console.log(`[mbkauthe] Schema applied successfully.`);
16
16
  if (res?.rows?.length) {
17
- console.log(res.rows);
17
+ console.log(`[mbkauthe] Rows returned by schema query:`, res.rows);
18
18
  } else {
19
- console.log("[mbkauthe] No rows returned by schema query (expected). If you want to verify table creation, query the database separately.");
19
+ console.log(`[mbkauthe] No rows returned by schema query (expected). If you want to verify table creation, query the database separately.`);
20
20
  }
21
21
  } catch (err) {
22
22
  const IGNORE_CODES = ["42710", "42P07"];
23
23
  if (err && typeof err.code === "string" && IGNORE_CODES.includes(err.code)) {
24
- console.warn("[mbkauthe] Schema already exists (ignored):", err.message);
24
+ console.warn(`[mbkauthe] Schema already exists (ignored):`, err.message);
25
25
  } else {
26
- console.error("[mbkauthe] Failed to apply schema:", err);
26
+ console.error(`[mbkauthe] Failed to apply schema:`, err);
27
27
  process.exitCode = 1;
28
28
  }
29
29
  } finally {
@@ -0,0 +1,295 @@
1
+ import { BaseRepository } from "./BaseRepository.js";
2
+
3
+ const OAUTH_PROVIDERS = {
4
+ github: {
5
+ table: "user_github",
6
+ idColumn: "github_id",
7
+ queryName: "github-login-get-user"
8
+ },
9
+ google: {
10
+ table: "user_google",
11
+ idColumn: "google_id",
12
+ queryName: "google-login-get-user"
13
+ }
14
+ };
15
+
16
+ export class AuthRepository extends BaseRepository {
17
+ resolveOAuthProvider(provider) {
18
+ const key = String(provider || "").toLowerCase();
19
+ const config = OAUTH_PROVIDERS[key];
20
+ if (!config) {
21
+ throw new Error(`Unsupported OAuth provider: ${provider}`);
22
+ }
23
+ return config;
24
+ }
25
+
26
+ async fetchActiveSession(sessionId) {
27
+ const query = `SELECT s.id as sid, s.expires_at, u.id as uid, u."UserName", u."Active", u."Role", u."AllowedApps"
28
+ FROM "Sessions" s
29
+ JOIN "Users" u ON s."UserName" = u."UserName"
30
+ WHERE s.id = $1 LIMIT 1`;
31
+ const result = await this.executeRaw({ name: "multi-session-fetch", text: query, values: [sessionId] });
32
+ return result.rows?.[0] || null;
33
+ }
34
+
35
+ async deleteAppSessionById(sessionId, queryName = "invalidate-app-session") {
36
+ const query = `DELETE FROM "Sessions" WHERE id = $1`;
37
+ return this.executeRaw({ name: queryName, text: query, values: [sessionId] });
38
+ }
39
+
40
+ async deleteSessionBySid(sessionId, queryName = "login-delete-old-session-before-regen") {
41
+ const query = `DELETE FROM "session" WHERE sid = $1`;
42
+ return this.executeRaw({ name: queryName, text: query, values: [sessionId] });
43
+ }
44
+
45
+ async touchTrustedDevice(deviceTokenHash, username) {
46
+ const query = `
47
+ UPDATE "TrustedDevices" td
48
+ SET "LastUsed" = NOW()
49
+ FROM "Users" u
50
+ WHERE td."DeviceToken" = $1
51
+ AND td."UserName" = $2
52
+ AND td."ExpiresAt" > NOW()
53
+ AND u."UserName" = td."UserName"
54
+ AND u."Active" = TRUE
55
+ RETURNING td."UserName", td."ExpiresAt", u."id" as id, u."Active", u."Role", u."AllowedApps"
56
+ `;
57
+
58
+ const result = await this.executeRaw({
59
+ name: "check-trusted-device",
60
+ text: query,
61
+ values: [deviceTokenHash, username]
62
+ });
63
+ return result.rows?.[0] || null;
64
+ }
65
+
66
+ async cleanupAndCountUserSessions(username, queryName = "cleanup-and-count-user-sessions") {
67
+ const query = `
68
+ WITH deleted AS (
69
+ DELETE FROM "Sessions"
70
+ WHERE "UserName" = $1
71
+ AND expires_at IS NOT NULL
72
+ AND expires_at <= NOW()
73
+ )
74
+ SELECT COUNT(*)::int AS count
75
+ FROM "Sessions"
76
+ WHERE "UserName" = $1
77
+ `;
78
+
79
+ const result = await this.executeRaw({ name: queryName, text: query, values: [username] });
80
+ return Number(result.rows?.[0]?.count ?? 0);
81
+ }
82
+
83
+ async deleteOldestSessionsForUser(username, limit, queryName = "prune-oldest-user-session") {
84
+ if (!Number.isFinite(limit) || limit <= 0) return 0;
85
+ const query = `DELETE FROM "Sessions" WHERE id IN (SELECT id FROM "Sessions" WHERE "UserName" = $1 ORDER BY created_at ASC LIMIT $2)`;
86
+ const result = await this.executeRaw({ name: queryName, text: query, values: [username, limit] });
87
+ return result.rowCount || 0;
88
+ }
89
+
90
+ async deleteExpiredSessionsForUser(username) {
91
+ const query = this.sql`
92
+ DELETE FROM ${this.table("Sessions")}
93
+ WHERE ${this.ident("UserName")} = ${this.value(username)}
94
+ AND ${this.ident("expires_at")} IS NOT NULL
95
+ AND ${this.ident("expires_at")} <= ${this.now()}
96
+ `;
97
+
98
+ const result = await this.execute("cleanup-expired-user-sessions", query);
99
+ return result.rowCount || 0;
100
+ }
101
+
102
+ async countActiveSessionsForUser(username) {
103
+ const columns = this.columns([`COUNT(*) AS ${this.quoteIdentifier("count")}`]);
104
+ const query = this.sql`
105
+ SELECT ${columns}
106
+ FROM ${this.table("Sessions")}
107
+ WHERE ${this.ident("UserName")} = ${this.value(username)}
108
+ `;
109
+ const result = await this.execute("count-user-sessions", query);
110
+ return Number(result.rows?.[0]?.count ?? 0);
111
+ }
112
+
113
+ async getOldestSessionIds(username, limit) {
114
+ if (!Number.isFinite(limit) || limit <= 0) return [];
115
+
116
+ const query = this.sql`
117
+ SELECT ${this.column("id")}
118
+ FROM ${this.table("Sessions")}
119
+ WHERE ${this.ident("UserName")} = ${this.value(username)}
120
+ ORDER BY ${this.ident("created_at")} ASC
121
+ ${this.limit(limit)}
122
+ `;
123
+
124
+ const result = await this.execute("oldest-user-sessions", query);
125
+ return (result.rows || []).map((row) => row.id).filter(Boolean);
126
+ }
127
+
128
+ async insertAppSession(username, expiresAt, meta) {
129
+ const query = `INSERT INTO "Sessions" ("UserName", expires_at, meta) VALUES ($1, $2, $3) RETURNING id`;
130
+ const result = await this.executeRaw({
131
+ name: "insert-app-session",
132
+ text: query,
133
+ values: [username, expiresAt, meta]
134
+ });
135
+ return result.rows?.[0] || null;
136
+ }
137
+
138
+ async updateLastLoginReturnProfile(userId) {
139
+ const query = `UPDATE "Users" SET "last_login" = NOW() WHERE "id" = $1 RETURNING "FullName", "Image"`;
140
+ const result = await this.executeRaw({
141
+ name: "login-update-last-login-return-profile",
142
+ text: query,
143
+ values: [userId]
144
+ });
145
+ return result.rows?.[0] || null;
146
+ }
147
+
148
+ async getUserProfileByUsername(username, queryName = "login-get-fullname-and-image") {
149
+ const query = `SELECT "FullName", "Image" FROM "Users" WHERE "UserName" = $1 LIMIT 1`;
150
+ const result = await this.executeRaw({ name: queryName, text: query, values: [username] });
151
+ return result.rows?.[0] || null;
152
+ }
153
+
154
+ async insertTrustedDevice({ username, deviceTokenHash, deviceName, userAgent, ipAddress, expiresAt }) {
155
+ const query = `INSERT INTO "TrustedDevices" ("UserName", "DeviceToken", "DeviceName", "UserAgent", "IpAddress", "ExpiresAt")
156
+ VALUES ($1, $2, $3, $4, $5, $6)`;
157
+ return this.executeRaw({
158
+ name: "insert-trusted-device",
159
+ text: query,
160
+ values: [username, deviceTokenHash, deviceName, userAgent, ipAddress, expiresAt]
161
+ });
162
+ }
163
+
164
+ async getUserWithTwoFA(username, queryName = "login-get-user") {
165
+ const query = `
166
+ SELECT u.id, u."UserName", u."PasswordEnc", u."Active", u."Role", u."AllowedApps",
167
+ tfa."TwoFAStatus"
168
+ FROM "Users" u
169
+ LEFT JOIN "TwoFA" tfa ON u."UserName" = tfa."UserName"
170
+ WHERE u."UserName" = $1
171
+ `;
172
+
173
+ const result = await this.executeRaw({ name: queryName, text: query, values: [username] });
174
+ return result.rows?.[0] || null;
175
+ }
176
+
177
+ async getTwoFASecret(username) {
178
+ const query = `SELECT tfa."TwoFASecret" FROM "TwoFA" tfa WHERE tfa."UserName" = $1`;
179
+ const result = await this.executeRaw({ name: "verify-2fa-secret", text: query, values: [username] });
180
+ return result.rows?.[0] || null;
181
+ }
182
+
183
+ async deleteSessionsByIds(ids, queryName = "delete-sessions-by-ids") {
184
+ if (!Array.isArray(ids) || ids.length === 0) return 0;
185
+ const query = `DELETE FROM "Sessions" WHERE id = ANY($1)`;
186
+ const result = await this.executeRaw({ name: queryName, text: query, values: [ids] });
187
+ return result.rowCount || 0;
188
+ }
189
+
190
+ async getOAuthUserByProviderId(provider, providerId) {
191
+ const { table, idColumn, queryName } = this.resolveOAuthProvider(provider);
192
+ const query = `SELECT ug.*, u."UserName", u."Role", u."Active", u."AllowedApps", u."id" FROM ${table} ug JOIN "Users" u ON ug.user_name = u."UserName" WHERE ug.${idColumn} = $1`;
193
+ const result = await this.executeRaw({ name: queryName, text: query, values: [providerId] });
194
+ return result.rows?.[0] || null;
195
+ }
196
+
197
+ async getApiTokenByHash(tokenHash, queryName = "validate-api-token") {
198
+ const query = `
199
+ SELECT t.id, t."UserName", t."ExpiresAt", t."Permissions",
200
+ u.id as uid, u."Active", u."Role", u."AllowedApps" as user_allowed_apps, u."FullName"
201
+ FROM "ApiTokens" t
202
+ JOIN "Users" u ON t."UserName" = u."UserName"
203
+ WHERE t."TokenHash" = $1 LIMIT 1
204
+ `;
205
+
206
+ const result = await this.executeRaw({ name: queryName, text: query, values: [tokenHash] });
207
+ return result.rows?.[0] || null;
208
+ }
209
+
210
+ async updateApiTokenLastUsed(tokenId, queryName = null) {
211
+ const query = `UPDATE "ApiTokens" SET "LastUsed" = NOW() WHERE id = $1`;
212
+ if (queryName) {
213
+ return this.executeRaw({ name: queryName, text: query, values: [tokenId] });
214
+ }
215
+ return this.executeRaw({ text: query, values: [tokenId] });
216
+ }
217
+
218
+ async getSessionAuthData(sessionId, queryName = "validate-app-session") {
219
+ const query = `
220
+ SELECT s.expires_at, u."Active", u."Role"
221
+ FROM "Sessions" s
222
+ JOIN "Users" u ON s."UserName" = u."UserName"
223
+ WHERE s.id = $1
224
+ LIMIT 1
225
+ `;
226
+
227
+ const result = await this.executeRaw({ name: queryName, text: query, values: [sessionId] });
228
+ return result.rows?.[0] || null;
229
+ }
230
+
231
+ async getSessionWithUserById(sessionId, queryName = "restore-user-session") {
232
+ const query = `SELECT u.id, u."UserName", u."Active", u."Role", u."AllowedApps", s.expires_at
233
+ FROM "Sessions" s
234
+ JOIN "Users" u ON s."UserName" = u."UserName"
235
+ WHERE s.id = $1 LIMIT 1`;
236
+ const result = await this.executeRaw({ name: queryName, text: query, values: [sessionId] });
237
+ return result.rows?.[0] || null;
238
+ }
239
+
240
+ async getSessionWithUserForReload(sessionId, queryName = "reload-session-user") {
241
+ const query = `SELECT s.id as sid, s.expires_at, u.id as uid, u."UserName", u."Active", u."Role", u."AllowedApps"
242
+ FROM "Sessions" s
243
+ JOIN "Users" u ON s."UserName" = u."UserName"
244
+ WHERE s.id = $1 LIMIT 1`;
245
+ const result = await this.executeRaw({ name: queryName, text: query, values: [sessionId] });
246
+ return result.rows?.[0] || null;
247
+ }
248
+
249
+ async getSessionValidationRow(sessionId, queryName = "check-session-validity-by-id") {
250
+ const query = `SELECT s.expires_at, u."Active", u."UserName", u."Role" FROM "Sessions" s JOIN "Users" u ON s."UserName" = u."UserName" WHERE s.id = $1 LIMIT 1`;
251
+ const result = await this.executeRaw({ name: queryName, text: query, values: [sessionId] });
252
+ return result.rows?.[0] || null;
253
+ }
254
+
255
+ async getUserFullNameByUsername(username, queryName = "get-fullname-by-username") {
256
+ const query = `SELECT "FullName" FROM "Users" WHERE "UserName" = $1 LIMIT 1`;
257
+ const result = await this.executeRaw({ name: queryName, text: query, values: [username] });
258
+ return result.rows?.[0] || null;
259
+ }
260
+
261
+ async getUserImageByUsername(username, queryName = "get-user-profile-pic") {
262
+ const query = `SELECT "Image" FROM "Users" WHERE "UserName" = $1 LIMIT 1`;
263
+ const result = await this.executeRaw({ name: queryName, text: query, values: [username] });
264
+ return result.rows?.[0] || null;
265
+ }
266
+
267
+ async getSessionValidity(sessionId, sessionStoreSid, queryName = "check-session-validity") {
268
+ const query = `
269
+ SELECT
270
+ s.expires_at,
271
+ u."Active",
272
+ CASE
273
+ WHEN s.expires_at IS NULL THEN (SELECT expire FROM "session" WHERE sid = $2)
274
+ ELSE NULL
275
+ END AS connect_expire
276
+ FROM "Sessions" s
277
+ JOIN "Users" u ON s."UserName" = u."UserName"
278
+ WHERE s.id = $1
279
+ LIMIT 1
280
+ `;
281
+
282
+ const result = await this.executeRaw({ name: queryName, text: query, values: [sessionId, sessionStoreSid] });
283
+ return result.rows?.[0] || null;
284
+ }
285
+
286
+ async deleteAllAppSessions(queryName = "delete-all-app-sessions") {
287
+ const query = `DELETE FROM "Sessions"`;
288
+ return this.executeRaw({ name: queryName, text: query, values: [] });
289
+ }
290
+
291
+ async deleteActiveSessionStoreRows(queryName = "delete-active-session-store-rows") {
292
+ const query = `DELETE FROM "session" WHERE expire > NOW()`;
293
+ return this.executeRaw({ name: queryName, text: query, values: [] });
294
+ }
295
+ }