http-mitm-proxy-ui 0.1.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/README.md +359 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +213 -0
- package/dist/index.js.map +1 -0
- package/dist/proxy/RequestStore.d.ts +31 -0
- package/dist/proxy/RequestStore.d.ts.map +1 -0
- package/dist/proxy/RequestStore.js +163 -0
- package/dist/proxy/RequestStore.js.map +1 -0
- package/dist/proxy/index.d.ts +56 -0
- package/dist/proxy/index.d.ts.map +1 -0
- package/dist/proxy/index.js +135 -0
- package/dist/proxy/index.js.map +1 -0
- package/dist/public/assets/index-BFoa2rnZ.js +3 -0
- package/dist/public/assets/index-DxoSovY1.css +1 -0
- package/dist/public/favicon.svg +1 -0
- package/dist/public/icons.svg +24 -0
- package/dist/public/index.html +14 -0
- package/dist/ui/server.d.ts +28 -0
- package/dist/ui/server.d.ts.map +1 -0
- package/dist/ui/server.js +319 -0
- package/dist/ui/server.js.map +1 -0
- package/package.json +55 -0
- package/patches/http-mitm-proxy+1.1.0.patch +53 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--color-primary:#d32f2f;--color-primary-dark:#b71c1c;--color-primary-light:#ef5350;--color-primary-bg:#ffebee;--color-black:#212121;--color-dark:#424242;--color-gray:#757575;--color-gray-light:#9e9e9e;--color-gray-lighter:#e0e0e0;--color-gray-lightest:#f5f5f5;--color-white:#fff;--color-success:#2e7d32;--color-success-bg:#e8f5e9;--color-warning:#f57c00;--color-warning-bg:#fff3e0;--color-error:#d32f2f;--color-error-bg:#ffebee;--color-info:#1976d2;--color-info-bg:#e3f2fd;--method-get:#1976d2;--method-post:#2e7d32;--method-put:#f57c00;--method-delete:#d32f2f;--method-patch:#7b1fa2;--method-other:#757575;--header-height:56px;--filter-bar-height:52px;--border-radius:4px;--border-radius-lg:8px;--shadow-sm:0 1px 3px #0000001f, 0 1px 2px #00000014;--shadow-md:0 3px 6px #00000029, 0 3px 6px #0000001f;--shadow-lg:0 10px 20px #00000030, 0 6px 6px #00000026;--font-family:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;--font-mono:"SF Mono", "Fira Code", "Fira Mono", "Roboto Mono", Consolas, monospace;--font-size-xs:.75rem;--font-size-sm:.8125rem;--font-size-base:.875rem;--font-size-lg:1rem;--font-size-xl:1.25rem;--font-size-2xl:1.5rem;--transition-fast:.15s ease;--transition-base:.2s ease;--transition-slow:.3s ease}*,:before,:after{box-sizing:border-box;margin:0;padding:0}html{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:16px}body{font-family:var(--font-family);font-size:var(--font-size-base);color:var(--color-black);background:var(--color-gray-lightest);line-height:1.5}.app-container{flex-direction:column;min-height:100vh;display:flex}.proxy-header{height:var(--header-height);background:var(--color-primary);color:var(--color-white);box-shadow:var(--shadow-md);z-index:100;justify-content:space-between;align-items:center;padding:0 16px;display:flex;position:sticky;top:0}.header-left{align-items:center;gap:8px;display:flex}.logo{font-size:var(--font-size-xl);letter-spacing:-.02em;align-items:center;gap:8px;font-weight:600;display:flex}.logo-icon{opacity:.9}.header-center{align-items:center;gap:16px;display:flex}.status-badge{font-size:var(--font-size-sm);background:#ffffff26;border-radius:16px;align-items:center;gap:6px;padding:4px 12px;display:inline-flex}.status-dot{background:currentColor;border-radius:50%;width:8px;height:8px}.status-running{color:#a5d6a7;background:#2e7d3233}.status-running .status-dot{background:#4caf50;animation:2s infinite pulse}.status-stopped{color:#ef9a9a;background:#d32f2f33}.status-stopped .status-dot{background:#f44336}.status-unknown{color:#fff9;background:#ffffff1a}.status-unknown .status-dot{background:#fff6}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}.request-counter{font-size:var(--font-size-sm);opacity:.9}.header-right{align-items:center;gap:8px;display:flex}.btn{border-radius:var(--border-radius);font-size:var(--font-size-sm);cursor:pointer;transition:all var(--transition-fast);white-space:nowrap;border:none;align-items:center;gap:6px;padding:6px 14px;font-weight:500;display:inline-flex}.btn:focus-visible{outline:2px solid var(--color-white);outline-offset:2px}.btn-outline{color:var(--color-white);background:#ffffff1a;border:1px solid #ffffff4d}.btn-outline:hover{background:#fff3}.btn-outline:not(.proxy-header .btn-outline){background:var(--color-white);color:var(--color-dark);border:1px solid var(--color-gray-lighter)}.btn-outline:not(.proxy-header .btn-outline):hover{background:var(--color-gray-lightest);border-color:var(--color-gray-light)}.btn-danger{color:var(--color-white);background:#ffffff26;border:1px solid #ffffff4d}.btn-danger:hover{background:#ffffff40}.btn-danger:not(.proxy-header .btn-danger){background:var(--color-error);color:var(--color-white);border:none}.btn-danger:not(.proxy-header .btn-danger):hover{background:var(--color-primary-dark)}.btn-sm{font-size:var(--font-size-xs);padding:4px 10px}.btn-primary{background:var(--color-primary);color:var(--color-white);border:none}.btn-primary:hover:not(:disabled){background:var(--color-primary-dark)}.btn-primary:disabled{opacity:.6;cursor:not-allowed}.btn-close{color:var(--color-gray);cursor:pointer;border-radius:var(--border-radius);transition:all var(--transition-fast);background:0 0;border:none;justify-content:center;align-items:center;padding:4px;display:inline-flex}.btn-close:hover{background:var(--color-gray-lightest);color:var(--color-black)}.btn-retry{border:1px solid var(--color-white);color:var(--color-white);border-radius:var(--border-radius);cursor:pointer;font-size:var(--font-size-sm);background:0 0;padding:4px 12px}.btn-retry:hover{background:#ffffff26}.main-content{flex-direction:column;flex:1;display:flex;overflow:hidden}.filter-bar{background:var(--color-white);border-bottom:1px solid var(--color-gray-lighter);min-height:var(--filter-bar-height);flex-wrap:wrap;align-items:center;gap:12px;padding:8px 16px;display:flex}.filter-group{align-items:center;gap:6px;display:flex}.filter-group label{font-size:var(--font-size-sm);color:var(--color-gray);white-space:nowrap;font-weight:500}.filter-group select,.filter-group input[type=text]{border:1px solid var(--color-gray-lighter);border-radius:var(--border-radius);font-size:var(--font-size-sm);background:var(--color-white);color:var(--color-black);min-width:100px;transition:border-color var(--transition-fast);padding:5px 10px}.filter-group select:focus,.filter-group input[type=text]:focus{border-color:var(--color-primary);box-shadow:0 0 0 2px var(--color-primary-bg);outline:none}.filter-domain{flex:1;min-width:150px}.filter-domain input{width:100%}.filter-search{flex:2;min-width:200px}.search-wrapper{flex:1;position:relative}.search-icon{color:var(--color-gray-light);pointer-events:none;position:absolute;top:50%;left:10px;transform:translateY(-50%)}.search-wrapper input{width:100%;padding-left:34px}.filter-actions{align-items:center;gap:8px;margin-left:auto;display:flex}.request-list-container{background:var(--color-white);flex:1;overflow:auto}.request-table{border-collapse:collapse;width:100%;font-size:var(--font-size-sm)}.request-table thead{z-index:10;background:var(--color-gray-lightest);position:sticky;top:0}.request-table th{text-align:left;color:var(--color-dark);border-bottom:2px solid var(--color-gray-lighter);white-space:nowrap;-webkit-user-select:none;user-select:none;padding:10px 12px;font-weight:600}.sort-header{cursor:pointer}.sort-header:hover{background:var(--color-gray-lighter)}.request-row{cursor:pointer;transition:background var(--transition-fast)}.request-row:hover{background:var(--color-gray-lightest)}.request-row.selected{background:var(--color-primary-bg)}.request-row.row-pending{opacity:.6}.request-table td{border-bottom:1px solid var(--color-gray-lighter);vertical-align:middle;padding:8px 12px}.method-badge{font-size:var(--font-size-xs);font-weight:700;font-family:var(--font-mono);color:var(--color-white);border-radius:3px;padding:2px 8px;display:inline-block}.method-get{background:var(--method-get)}.method-post{background:var(--method-post)}.method-put{background:var(--method-put)}.method-delete{background:var(--method-delete)}.method-patch{background:var(--method-patch)}.method-other{background:var(--method-other)}.url-cell{text-overflow:ellipsis;white-space:nowrap;max-width:400px;font-family:var(--font-mono);font-size:var(--font-size-xs);overflow:hidden}.domain-cell{text-overflow:ellipsis;white-space:nowrap;max-width:150px;color:var(--color-gray);font-size:var(--font-size-xs);overflow:hidden}.time-cell{white-space:nowrap;font-family:var(--font-mono);font-size:var(--font-size-xs);color:var(--color-gray)}.status-badge{font-size:var(--font-size-xs);font-weight:600;font-family:var(--font-mono);border-radius:3px;padding:2px 8px;display:inline-block}.status-2xx,.status-pending{background:var(--color-success-bg);color:var(--color-success)}.status-3xx{background:var(--color-info-bg);color:var(--color-info)}.status-4xx{background:var(--color-warning-bg);color:var(--color-warning)}.status-5xx,.status-other{background:var(--color-error-bg);color:var(--color-error)}.empty-state{text-align:center;color:var(--color-gray);flex-direction:column;justify-content:center;align-items:center;padding:60px 20px;display:flex}.empty-icon{opacity:.4;margin-bottom:16px}.empty-state h3{font-size:var(--font-size-xl);color:var(--color-dark);margin-bottom:8px}.empty-state p{font-size:var(--font-size-base);max-width:500px;margin-bottom:24px}.empty-state code{background:var(--color-gray-lightest);font-family:var(--font-mono);font-size:var(--font-size-sm);border-radius:3px;padding:2px 6px}.empty-steps{text-align:left;flex-direction:column;gap:12px;display:flex}.step{background:var(--color-gray-lightest);border-radius:var(--border-radius);align-items:center;gap:12px;padding:12px 16px;display:flex}.step-number{background:var(--color-primary);width:28px;height:28px;color:var(--color-white);font-weight:700;font-size:var(--font-size-sm);border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;display:flex}.error-banner{background:var(--color-error);color:var(--color-white);font-size:var(--font-size-sm);justify-content:space-between;align-items:center;padding:12px 16px;display:flex}.loading-indicator{color:var(--color-gray);font-size:var(--font-size-sm);justify-content:center;align-items:center;gap:12px;padding:40px;display:flex}.spinner{border:3px solid var(--color-gray-lighter);border-top-color:var(--color-primary);border-radius:50%;width:24px;height:24px;animation:.8s linear infinite spin}@keyframes spin{to{transform:rotate(360deg)}}.detail-overlay{z-index:200;background:#0006;justify-content:flex-end;display:flex;position:fixed;inset:0}.detail-panel{background:var(--color-white);width:min(700px,90vw);height:100%;box-shadow:var(--shadow-lg);flex-direction:column;display:flex;overflow:hidden}.detail-header{border-bottom:1px solid var(--color-gray-lighter);background:var(--color-gray-lightest);justify-content:space-between;align-items:center;padding:16px;display:flex}.detail-title{font-size:var(--font-size-lg);flex:1;align-items:center;gap:10px;min-width:0;display:flex}.detail-url{text-overflow:ellipsis;white-space:nowrap;font-family:var(--font-mono);font-size:var(--font-size-sm);color:var(--color-gray);font-weight:400;overflow:hidden}.detail-loading,.detail-error{color:var(--color-gray);flex-direction:column;justify-content:center;align-items:center;gap:12px;padding:60px 20px;display:flex}.detail-error{color:var(--color-error)}.detail-tabs{border-bottom:1px solid var(--color-gray-lighter);background:var(--color-white);display:flex}.detail-tab{color:var(--color-gray);font-size:var(--font-size-sm);cursor:pointer;transition:all var(--transition-fast);background:0 0;border:none;border-bottom:2px solid #0000;padding:12px 20px;font-weight:500}.detail-tab:hover{color:var(--color-black);background:var(--color-gray-lightest)}.detail-tab.active{color:var(--color-primary);border-bottom-color:var(--color-primary)}.detail-content{flex:1;padding:16px;overflow:auto}.tab-content{flex-direction:column;gap:16px;display:flex}.detail-section h3{font-size:var(--font-size-base);color:var(--color-dark);align-items:center;gap:8px;margin-bottom:10px;display:flex}.body-content{background:var(--color-gray-lightest);border:1px solid var(--color-gray-lighter);border-radius:var(--border-radius);font-family:var(--font-mono);font-size:var(--font-size-xs);white-space:pre-wrap;word-break:break-all;max-height:400px;padding:12px;overflow:auto}.no-response{color:var(--color-gray-light);text-align:center;padding:20px;font-style:italic}.detail-meta{grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:10px;display:grid}.meta-item{background:var(--color-gray-lightest);border-radius:var(--border-radius);flex-direction:column;gap:2px;padding:8px 12px;display:flex}.meta-label{font-size:var(--font-size-xs);color:var(--color-gray);text-transform:uppercase;letter-spacing:.05em;font-weight:500}.meta-value{font-size:var(--font-size-sm);color:var(--color-black);font-family:var(--font-mono);word-break:break-all}.headers-table{border-collapse:collapse;width:100%;font-size:var(--font-size-xs)}.headers-table td{border-bottom:1px solid var(--color-gray-lighter);padding:6px 10px}.header-name{color:var(--color-dark);white-space:nowrap;width:180px;font-weight:600}.header-value{font-family:var(--font-mono);word-break:break-all;color:var(--color-gray)}.modal-overlay{z-index:300;background:#00000080;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.modal-dialog{background:var(--color-white);border-radius:var(--border-radius-lg);width:min(500px,90vw);box-shadow:var(--shadow-lg);overflow:hidden}.modal-header{border-bottom:1px solid var(--color-gray-lighter);justify-content:space-between;align-items:center;padding:16px 20px;display:flex}.modal-header h3{font-size:var(--font-size-lg)}.modal-body{flex-direction:column;gap:16px;padding:20px;display:flex}.modal-footer{border-top:1px solid var(--color-gray-lighter);background:var(--color-gray-lightest);justify-content:flex-end;align-items:center;gap:8px;padding:12px 20px;display:flex}.form-group{flex-direction:column;gap:4px;display:flex}.form-group label{font-size:var(--font-size-sm);color:var(--color-dark);font-weight:500}.form-group select{border:1px solid var(--color-gray-lighter);border-radius:var(--border-radius);font-size:var(--font-size-sm);background:var(--color-white);padding:8px 12px}.form-group select:focus{border-color:var(--color-primary);box-shadow:0 0 0 2px var(--color-primary-bg);outline:none}.export-progress{flex-direction:column;gap:6px;display:flex}.progress-bar{background:var(--color-gray-lighter);border-radius:3px;height:6px;overflow:hidden}.progress-fill{background:var(--color-primary);height:100%;transition:width var(--transition-base)}.export-progress span{font-size:var(--font-size-xs);color:var(--color-gray)}.slide-panel-enter-active,.slide-panel-leave-active{transition:all var(--transition-slow)}.slide-panel-enter-from,.slide-panel-leave-to{opacity:0;transform:translate(100%)}@media (width<=768px){.proxy-header{padding:0 12px}.logo{font-size:var(--font-size-lg)}.header-center{gap:8px}.status-badge{font-size:var(--font-size-xs);padding:3px 8px}.request-counter{display:none}.filter-bar{gap:8px;padding:8px 12px}.filter-group{flex:1;min-width:0}.filter-group select,.filter-group input[type=text]{width:100%;min-width:0}.filter-search{flex-basis:100%;order:10}.filter-actions{margin-left:0}.url-cell{max-width:200px}.domain-cell{display:none}.detail-panel{width:100vw}.detail-meta{grid-template-columns:1fr}}@media (width<=480px){.header-right .btn span{display:none}.method-badge,.status-badge{padding:1px 5px;font-size:.65rem}}:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}button:focus:not(:focus-visible){outline:none}.sr-only{clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="46" fill="none" viewBox="0 0 48 46"><path fill="#863bff" d="M25.946 44.938c-.664.845-2.021.375-2.021-.698V33.937a2.26 2.26 0 0 0-2.262-2.262H10.287c-.92 0-1.456-1.04-.92-1.788l7.48-10.471c1.07-1.497 0-3.578-1.842-3.578H1.237c-.92 0-1.456-1.04-.92-1.788L10.013.474c.214-.297.556-.474.92-.474h28.894c.92 0 1.456 1.04.92 1.788l-7.48 10.471c-1.07 1.498 0 3.579 1.842 3.579h11.377c.943 0 1.473 1.088.89 1.83L25.947 44.94z" style="fill:#863bff;fill:color(display-p3 .5252 .23 1);fill-opacity:1"/><mask id="a" width="48" height="46" x="0" y="0" maskUnits="userSpaceOnUse" style="mask-type:alpha"><path fill="#000" d="M25.842 44.938c-.664.844-2.021.375-2.021-.698V33.937a2.26 2.26 0 0 0-2.262-2.262H10.183c-.92 0-1.456-1.04-.92-1.788l7.48-10.471c1.07-1.498 0-3.579-1.842-3.579H1.133c-.92 0-1.456-1.04-.92-1.787L9.91.473c.214-.297.556-.474.92-.474h28.894c.92 0 1.456 1.04.92 1.788l-7.48 10.471c-1.07 1.498 0 3.578 1.842 3.578h11.377c.943 0 1.473 1.088.89 1.832L25.843 44.94z" style="fill:#000;fill-opacity:1"/></mask><g mask="url(#a)"><g filter="url(#b)"><ellipse cx="5.508" cy="14.704" fill="#ede6ff" rx="5.508" ry="14.704" style="fill:#ede6ff;fill:color(display-p3 .9275 .9033 1);fill-opacity:1" transform="matrix(.00324 1 1 -.00324 -4.47 31.516)"/></g><g filter="url(#c)"><ellipse cx="10.399" cy="29.851" fill="#ede6ff" rx="10.399" ry="29.851" style="fill:#ede6ff;fill:color(display-p3 .9275 .9033 1);fill-opacity:1" transform="matrix(.00324 1 1 -.00324 -39.328 7.883)"/></g><g filter="url(#d)"><ellipse cx="5.508" cy="30.487" fill="#7e14ff" rx="5.508" ry="30.487" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(89.814 -25.913 -14.639)scale(1 -1)"/></g><g filter="url(#e)"><ellipse cx="5.508" cy="30.599" fill="#7e14ff" rx="5.508" ry="30.599" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(89.814 -32.644 -3.334)scale(1 -1)"/></g><g filter="url(#f)"><ellipse cx="5.508" cy="30.599" fill="#7e14ff" rx="5.508" ry="30.599" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="matrix(.00324 1 1 -.00324 -34.34 30.47)"/></g><g filter="url(#g)"><ellipse cx="14.072" cy="22.078" fill="#ede6ff" rx="14.072" ry="22.078" style="fill:#ede6ff;fill:color(display-p3 .9275 .9033 1);fill-opacity:1" transform="rotate(93.35 24.506 48.493)scale(-1 1)"/></g><g filter="url(#h)"><ellipse cx="3.47" cy="21.501" fill="#7e14ff" rx="3.47" ry="21.501" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(89.009 28.708 47.59)scale(-1 1)"/></g><g filter="url(#i)"><ellipse cx="3.47" cy="21.501" fill="#7e14ff" rx="3.47" ry="21.501" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(89.009 28.708 47.59)scale(-1 1)"/></g><g filter="url(#j)"><ellipse cx=".387" cy="8.972" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(39.51 .387 8.972)"/></g><g filter="url(#k)"><ellipse cx="47.523" cy="-6.092" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(37.892 47.523 -6.092)"/></g><g filter="url(#l)"><ellipse cx="41.412" cy="6.333" fill="#47bfff" rx="5.971" ry="9.665" style="fill:#47bfff;fill:color(display-p3 .2799 .748 1);fill-opacity:1" transform="rotate(37.892 41.412 6.333)"/></g><g filter="url(#m)"><ellipse cx="-1.879" cy="38.332" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(37.892 -1.88 38.332)"/></g><g filter="url(#n)"><ellipse cx="-1.879" cy="38.332" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(37.892 -1.88 38.332)"/></g><g filter="url(#o)"><ellipse cx="35.651" cy="29.907" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(37.892 35.651 29.907)"/></g><g filter="url(#p)"><ellipse cx="38.418" cy="32.4" fill="#47bfff" rx="5.971" ry="15.297" style="fill:#47bfff;fill:color(display-p3 .2799 .748 1);fill-opacity:1" transform="rotate(37.892 38.418 32.4)"/></g></g><defs><filter id="b" width="60.045" height="41.654" x="-19.77" y="16.149" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="7.659"/></filter><filter id="c" width="90.34" height="51.437" x="-54.613" y="-7.533" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="7.659"/></filter><filter id="d" width="79.355" height="29.4" x="-49.64" y="2.03" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="e" width="79.579" height="29.4" x="-45.045" y="20.029" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="f" width="79.579" height="29.4" x="-43.513" y="21.178" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="g" width="74.749" height="58.852" x="15.756" y="-17.901" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="7.659"/></filter><filter id="h" width="61.377" height="25.362" x="23.548" y="2.284" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="i" width="61.377" height="25.362" x="23.548" y="2.284" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="j" width="56.045" height="63.649" x="-27.636" y="-22.853" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="k" width="54.814" height="64.646" x="20.116" y="-38.415" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="l" width="33.541" height="35.313" x="24.641" y="-11.323" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="m" width="54.814" height="64.646" x="-29.286" y="6.009" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="n" width="54.814" height="64.646" x="-29.286" y="6.009" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="o" width="54.814" height="64.646" x="8.244" y="-2.416" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="p" width="39.409" height="43.623" x="18.713" y="10.588" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter></defs></svg>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<symbol id="bluesky-icon" viewBox="0 0 16 17">
|
|
3
|
+
<g clip-path="url(#bluesky-clip)"><path fill="#08060d" d="M7.75 7.735c-.693-1.348-2.58-3.86-4.334-5.097-1.68-1.187-2.32-.981-2.74-.79C.188 2.065.1 2.812.1 3.251s.241 3.602.398 4.13c.52 1.744 2.367 2.333 4.07 2.145-2.495.37-4.71 1.278-1.805 4.512 3.196 3.309 4.38-.71 4.987-2.746.608 2.036 1.307 5.91 4.93 2.746 2.72-2.746.747-4.143-1.747-4.512 1.702.189 3.55-.4 4.07-2.145.156-.528.397-3.691.397-4.13s-.088-1.186-.575-1.406c-.42-.19-1.06-.395-2.741.79-1.755 1.24-3.64 3.752-4.334 5.099"/></g>
|
|
4
|
+
<defs><clipPath id="bluesky-clip"><path fill="#fff" d="M.1.85h15.3v15.3H.1z"/></clipPath></defs>
|
|
5
|
+
</symbol>
|
|
6
|
+
<symbol id="discord-icon" viewBox="0 0 20 19">
|
|
7
|
+
<path fill="#08060d" d="M16.224 3.768a14.5 14.5 0 0 0-3.67-1.153c-.158.286-.343.67-.47.976a13.5 13.5 0 0 0-4.067 0c-.128-.306-.317-.69-.476-.976A14.4 14.4 0 0 0 3.868 3.77C1.546 7.28.916 10.703 1.231 14.077a14.7 14.7 0 0 0 4.5 2.306q.545-.748.965-1.587a9.5 9.5 0 0 1-1.518-.74q.191-.14.372-.293c2.927 1.369 6.107 1.369 8.999 0q.183.152.372.294-.723.437-1.52.74.418.838.963 1.588a14.6 14.6 0 0 0 4.504-2.308c.37-3.911-.63-7.302-2.644-10.309m-9.13 8.234c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.894 0 1.614.82 1.599 1.82.001 1-.705 1.82-1.6 1.82m5.91 0c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.893 0 1.614.82 1.599 1.82 0 1-.706 1.82-1.6 1.82"/>
|
|
8
|
+
</symbol>
|
|
9
|
+
<symbol id="documentation-icon" viewBox="0 0 21 20">
|
|
10
|
+
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="m15.5 13.333 1.533 1.322c.645.555.967.833.967 1.178s-.322.623-.967 1.179L15.5 18.333m-3.333-5-1.534 1.322c-.644.555-.966.833-.966 1.178s.322.623.966 1.179l1.534 1.321"/>
|
|
11
|
+
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M17.167 10.836v-4.32c0-1.41 0-2.117-.224-2.68-.359-.906-1.118-1.621-2.08-1.96-.599-.21-1.349-.21-2.848-.21-2.623 0-3.935 0-4.983.369-1.684.591-3.013 1.842-3.641 3.428C3 6.449 3 7.684 3 10.154v2.122c0 2.558 0 3.838.706 4.726q.306.383.713.671c.76.536 1.79.64 3.581.66"/>
|
|
12
|
+
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M3 10a2.78 2.78 0 0 1 2.778-2.778c.555 0 1.209.097 1.748-.047.48-.129.854-.503.982-.982.145-.54.048-1.194.048-1.749a2.78 2.78 0 0 1 2.777-2.777"/>
|
|
13
|
+
</symbol>
|
|
14
|
+
<symbol id="github-icon" viewBox="0 0 19 19">
|
|
15
|
+
<path fill="#08060d" fill-rule="evenodd" d="M9.356 1.85C5.05 1.85 1.57 5.356 1.57 9.694a7.84 7.84 0 0 0 5.324 7.44c.387.079.528-.168.528-.376 0-.182-.013-.805-.013-1.454-2.165.467-2.616-.935-2.616-.935-.349-.91-.864-1.143-.864-1.143-.71-.48.051-.48.051-.48.787.051 1.2.805 1.2.805.695 1.194 1.817.857 2.268.649.064-.507.27-.857.49-1.052-1.728-.182-3.545-.857-3.545-3.87 0-.857.31-1.558.8-2.104-.078-.195-.349-1 .077-2.078 0 0 .657-.208 2.14.805a7.5 7.5 0 0 1 1.946-.26c.657 0 1.328.092 1.946.26 1.483-1.013 2.14-.805 2.14-.805.426 1.078.155 1.883.078 2.078.502.546.799 1.247.799 2.104 0 3.013-1.818 3.675-3.558 3.87.284.247.528.714.528 1.454 0 1.052-.012 1.896-.012 2.156 0 .208.142.455.528.377a7.84 7.84 0 0 0 5.324-7.441c.013-4.338-3.48-7.844-7.773-7.844" clip-rule="evenodd"/>
|
|
16
|
+
</symbol>
|
|
17
|
+
<symbol id="social-icon" viewBox="0 0 20 20">
|
|
18
|
+
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M12.5 6.667a4.167 4.167 0 1 0-8.334 0 4.167 4.167 0 0 0 8.334 0"/>
|
|
19
|
+
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M2.5 16.667a5.833 5.833 0 0 1 8.75-5.053m3.837.474.513 1.035c.07.144.257.282.414.309l.93.155c.596.1.736.536.307.965l-.723.73a.64.64 0 0 0-.152.531l.207.903c.164.715-.213.991-.84.618l-.872-.52a.63.63 0 0 0-.577 0l-.872.52c-.624.373-1.003.094-.84-.618l.207-.903a.64.64 0 0 0-.152-.532l-.723-.729c-.426-.43-.289-.864.306-.964l.93-.156a.64.64 0 0 0 .412-.31l.513-1.034c.28-.562.735-.562 1.012 0"/>
|
|
20
|
+
</symbol>
|
|
21
|
+
<symbol id="x-icon" viewBox="0 0 19 19">
|
|
22
|
+
<path fill="#08060d" fill-rule="evenodd" d="M1.893 1.98c.052.072 1.245 1.769 2.653 3.77l2.892 4.114c.183.261.333.48.333.486s-.068.089-.152.183l-.522.593-.765.867-3.597 4.087c-.375.426-.734.834-.798.905a1 1 0 0 0-.118.148c0 .01.236.017.664.017h.663l.729-.83c.4-.457.796-.906.879-.999a692 692 0 0 0 1.794-2.038c.034-.037.301-.34.594-.675l.551-.624.345-.392a7 7 0 0 1 .34-.374c.006 0 .93 1.306 2.052 2.903l2.084 2.965.045.063h2.275c1.87 0 2.273-.003 2.266-.021-.008-.02-1.098-1.572-3.894-5.547-2.013-2.862-2.28-3.246-2.273-3.266.008-.019.282-.332 2.085-2.38l2-2.274 1.567-1.782c.022-.028-.016-.03-.65-.03h-.674l-.3.342a871 871 0 0 1-1.782 2.025c-.067.075-.405.458-.75.852a100 100 0 0 1-.803.91c-.148.172-.299.344-.99 1.127-.304.343-.32.358-.345.327-.015-.019-.904-1.282-1.976-2.808L6.365 1.85H1.8zm1.782.91 8.078 11.294c.772 1.08 1.413 1.973 1.425 1.984.016.017.241.02 1.05.017l1.03-.004-2.694-3.766L7.796 5.75 5.722 2.852l-1.039-.004-1.039-.004z" clip-rule="evenodd"/>
|
|
23
|
+
</symbol>
|
|
24
|
+
</svg>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="./favicon.svg" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>HTTP MITM Proxy</title>
|
|
8
|
+
<script type="module" crossorigin src="./assets/index-BFoa2rnZ.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="./assets/index-DxoSovY1.css">
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<div id="app"></div>
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { MitmProxy, ProxyUIConfig } from '../proxy';
|
|
2
|
+
import { EventEmitter } from 'events';
|
|
3
|
+
export declare class UIServer extends EventEmitter {
|
|
4
|
+
private app;
|
|
5
|
+
private httpServer;
|
|
6
|
+
private wss;
|
|
7
|
+
private config;
|
|
8
|
+
private proxy;
|
|
9
|
+
private clients;
|
|
10
|
+
private uiDistPath;
|
|
11
|
+
constructor(proxy: MitmProxy, config: ProxyUIConfig);
|
|
12
|
+
private setupMiddleware;
|
|
13
|
+
private setupRoutes;
|
|
14
|
+
/**
|
|
15
|
+
* Filter requests by method, status code, domain, content type, and full-text search.
|
|
16
|
+
*/
|
|
17
|
+
private filterRequests;
|
|
18
|
+
private setupWebSocket;
|
|
19
|
+
/**
|
|
20
|
+
* Handle incoming WebSocket messages from the client.
|
|
21
|
+
*/
|
|
22
|
+
private handleClientMessage;
|
|
23
|
+
private setupProxyEvents;
|
|
24
|
+
private broadcast;
|
|
25
|
+
start(): Promise<void>;
|
|
26
|
+
stop(): void;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/ui/server.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,SAAS,EAAiB,aAAa,EAAE,MAAM,UAAU,CAAA;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AAmBrC,qBAAa,QAAS,SAAQ,YAAY;IACxC,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,UAAU,CAAY;IAC9B,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,KAAK,CAAW;IACxB,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,UAAU,CAAQ;gBAEd,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa;IAcnD,OAAO,CAAC,eAAe;IAoBvB,OAAO,CAAC,WAAW;IA0FnB;;OAEG;IACH,OAAO,CAAC,cAAc;IAmEtB,OAAO,CAAC,cAAc;IAiCtB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAa3B,OAAO,CAAC,gBAAgB;IAuBxB,OAAO,CAAC,SAAS;IASX,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAW5B,IAAI,IAAI,IAAI;CAKb"}
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.UIServer = void 0;
|
|
40
|
+
const express_1 = __importDefault(require("express"));
|
|
41
|
+
const http_1 = require("http");
|
|
42
|
+
const ws_1 = require("ws");
|
|
43
|
+
const path = __importStar(require("path"));
|
|
44
|
+
const fs = __importStar(require("fs"));
|
|
45
|
+
const events_1 = require("events");
|
|
46
|
+
class UIServer extends events_1.EventEmitter {
|
|
47
|
+
app;
|
|
48
|
+
httpServer;
|
|
49
|
+
wss;
|
|
50
|
+
config;
|
|
51
|
+
proxy;
|
|
52
|
+
clients = new Set();
|
|
53
|
+
uiDistPath;
|
|
54
|
+
constructor(proxy, config) {
|
|
55
|
+
super();
|
|
56
|
+
this.proxy = proxy;
|
|
57
|
+
this.config = config;
|
|
58
|
+
this.uiDistPath = path.resolve(__dirname, '..', 'public');
|
|
59
|
+
this.app = (0, express_1.default)();
|
|
60
|
+
this.httpServer = (0, http_1.createServer)(this.app);
|
|
61
|
+
this.wss = new ws_1.WebSocketServer({ server: this.httpServer, path: '/ws' });
|
|
62
|
+
this.setupMiddleware();
|
|
63
|
+
this.setupRoutes();
|
|
64
|
+
this.setupWebSocket();
|
|
65
|
+
this.setupProxyEvents();
|
|
66
|
+
}
|
|
67
|
+
setupMiddleware() {
|
|
68
|
+
this.app.use(express_1.default.json({ limit: '10mb' }));
|
|
69
|
+
this.app.use(express_1.default.urlencoded({ extended: true }));
|
|
70
|
+
// CORS for localhost only
|
|
71
|
+
this.app.use((req, res, next) => {
|
|
72
|
+
const origin = req.headers.origin;
|
|
73
|
+
if (origin && /^https?:\/\/localhost:\d+$/.test(origin)) {
|
|
74
|
+
res.header('Access-Control-Allow-Origin', origin);
|
|
75
|
+
res.header('Access-Control-Allow-Methods', 'GET, DELETE, OPTIONS');
|
|
76
|
+
res.header('Access-Control-Allow-Headers', 'Content-Type');
|
|
77
|
+
}
|
|
78
|
+
if (req.method === 'OPTIONS') {
|
|
79
|
+
res.sendStatus(204);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
next();
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
setupRoutes() {
|
|
86
|
+
// Health check
|
|
87
|
+
this.app.get('/api/health', (_req, res) => {
|
|
88
|
+
res.json({ status: 'ok', uptime: process.uptime() });
|
|
89
|
+
});
|
|
90
|
+
// GET /api/requests — list with filtering & pagination
|
|
91
|
+
this.app.get('/api/requests', (req, res) => {
|
|
92
|
+
const queries = req.query;
|
|
93
|
+
const requests = this.proxy.getRequests();
|
|
94
|
+
const filtered = this.filterRequests(requests, queries);
|
|
95
|
+
const limit = Math.min(parseInt(queries.limit || '100', 10), this.config.maxRequests);
|
|
96
|
+
const offset = parseInt(queries.offset || '0', 10);
|
|
97
|
+
const paginated = filtered.slice(offset, offset + limit);
|
|
98
|
+
const response = {
|
|
99
|
+
data: paginated,
|
|
100
|
+
total: filtered.length,
|
|
101
|
+
limit,
|
|
102
|
+
offset,
|
|
103
|
+
};
|
|
104
|
+
res.json(response);
|
|
105
|
+
});
|
|
106
|
+
// GET /api/requests/:id — single request detail
|
|
107
|
+
this.app.get('/api/requests/:id', (req, res) => {
|
|
108
|
+
const id = Array.isArray(req.params.id) ? req.params.id[0] : req.params.id;
|
|
109
|
+
if (!id) {
|
|
110
|
+
res.status(400).json({ error: 'Missing request ID' });
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const request = this.proxy.getRequest(id);
|
|
114
|
+
if (request) {
|
|
115
|
+
res.json(request);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
res.status(404).json({ error: 'Request not found' });
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
// DELETE /api/requests — clear history
|
|
122
|
+
this.app.delete('/api/requests', async (_req, res) => {
|
|
123
|
+
await this.proxy.clearRequests();
|
|
124
|
+
this.broadcast({ type: 'clear', data: {} });
|
|
125
|
+
res.json({ message: 'Requests cleared' });
|
|
126
|
+
});
|
|
127
|
+
// GET /api/config — UI configuration
|
|
128
|
+
this.app.get('/api/config', (_req, res) => {
|
|
129
|
+
res.json({
|
|
130
|
+
proxyPort: this.config.proxyPort,
|
|
131
|
+
uiPort: this.config.uiPort,
|
|
132
|
+
headless: this.config.headless,
|
|
133
|
+
enableModification: this.config.enableModification,
|
|
134
|
+
maxRequests: this.config.maxRequests,
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
// GET /api/ca-cert — download CA certificate for trust installation
|
|
138
|
+
this.app.get('/api/ca-cert', (_req, res) => {
|
|
139
|
+
const caCertPath = this.config.sslCaDir
|
|
140
|
+
? path.join(this.config.sslCaDir, 'certs', 'ca.pem')
|
|
141
|
+
: null;
|
|
142
|
+
if (caCertPath && fs.existsSync(caCertPath)) {
|
|
143
|
+
res.download(caCertPath, 'http-mitm-proxy-ui-ca.pem');
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
res.status(404).json({
|
|
147
|
+
error: 'CA certificate not found. Start the proxy with --ssl-ca-dir to generate it.',
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
// Serve static files from the Vue build output
|
|
152
|
+
if (fs.existsSync(this.uiDistPath)) {
|
|
153
|
+
this.app.use(express_1.default.static(this.uiDistPath, { maxAge: '1d' }));
|
|
154
|
+
}
|
|
155
|
+
// Catch-all: serve index.html for SPA routing (handles all HTTP methods)
|
|
156
|
+
this.app.use((_req, res) => {
|
|
157
|
+
const indexPath = path.join(this.uiDistPath, 'index.html');
|
|
158
|
+
if (fs.existsSync(indexPath)) {
|
|
159
|
+
res.sendFile(indexPath);
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
res.status(404).json({
|
|
163
|
+
error: 'UI not built. Run `npm run build` or start with `npm run dev`.',
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Filter requests by method, status code, domain, content type, and full-text search.
|
|
170
|
+
*/
|
|
171
|
+
filterRequests(requests, query) {
|
|
172
|
+
let filtered = requests;
|
|
173
|
+
// Filter by HTTP method
|
|
174
|
+
if (query.method) {
|
|
175
|
+
const methods = query.method
|
|
176
|
+
.toUpperCase()
|
|
177
|
+
.split(',')
|
|
178
|
+
.map((m) => m.trim());
|
|
179
|
+
filtered = filtered.filter((r) => methods.includes(r.method.toUpperCase()));
|
|
180
|
+
}
|
|
181
|
+
// Filter by status code (supports ranges like "2xx", "4xx", or exact codes)
|
|
182
|
+
if (query.status) {
|
|
183
|
+
const statusFilters = query.status.split(',').map((s) => s.trim());
|
|
184
|
+
filtered = filtered.filter((r) => {
|
|
185
|
+
const status = r.response?.statusCode;
|
|
186
|
+
if (!status)
|
|
187
|
+
return false;
|
|
188
|
+
return statusFilters.some((filter) => {
|
|
189
|
+
if (filter.endsWith('xx')) {
|
|
190
|
+
const firstChar = filter.at(0);
|
|
191
|
+
if (!firstChar)
|
|
192
|
+
return false;
|
|
193
|
+
const digit = parseInt(firstChar, 10);
|
|
194
|
+
if (isNaN(digit))
|
|
195
|
+
return false;
|
|
196
|
+
const rangeStart = digit * 100;
|
|
197
|
+
return status >= rangeStart && status < rangeStart + 100;
|
|
198
|
+
}
|
|
199
|
+
return status === parseInt(filter, 10);
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
// Filter by domain/host
|
|
204
|
+
if (query.domain) {
|
|
205
|
+
const domainLower = query.domain.toLowerCase();
|
|
206
|
+
filtered = filtered.filter((r) => r.url.toLowerCase().includes(domainLower));
|
|
207
|
+
}
|
|
208
|
+
// Filter by content type
|
|
209
|
+
if (query.contentType) {
|
|
210
|
+
const ctLower = query.contentType.toLowerCase();
|
|
211
|
+
filtered = filtered.filter((r) => {
|
|
212
|
+
const reqCt = r.contentType?.toLowerCase() || '';
|
|
213
|
+
const resCt = r.response?.contentType?.toLowerCase() || '';
|
|
214
|
+
return reqCt.includes(ctLower) || resCt.includes(ctLower);
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
// Full-text search across URL, method, body
|
|
218
|
+
if (query.search) {
|
|
219
|
+
const searchLower = query.search.toLowerCase();
|
|
220
|
+
filtered = filtered.filter((r) => {
|
|
221
|
+
const urlMatch = r.url.toLowerCase().includes(searchLower);
|
|
222
|
+
const methodMatch = r.method.toLowerCase().includes(searchLower);
|
|
223
|
+
const bodyMatch = typeof r.body === 'string' ? r.body.toLowerCase().includes(searchLower) : false;
|
|
224
|
+
const responseBodyMatch = typeof r.response?.body === 'string'
|
|
225
|
+
? r.response.body.toLowerCase().includes(searchLower)
|
|
226
|
+
: false;
|
|
227
|
+
return urlMatch || methodMatch || bodyMatch || responseBodyMatch;
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
return filtered;
|
|
231
|
+
}
|
|
232
|
+
setupWebSocket() {
|
|
233
|
+
this.wss.on('connection', (ws) => {
|
|
234
|
+
this.clients.add(ws);
|
|
235
|
+
ws.on('close', () => {
|
|
236
|
+
this.clients.delete(ws);
|
|
237
|
+
});
|
|
238
|
+
ws.on('error', (err) => {
|
|
239
|
+
console.error('WebSocket error:', err.message);
|
|
240
|
+
this.clients.delete(ws);
|
|
241
|
+
});
|
|
242
|
+
ws.on('message', (raw) => {
|
|
243
|
+
try {
|
|
244
|
+
const msg = JSON.parse(raw.toString());
|
|
245
|
+
this.handleClientMessage(ws, msg);
|
|
246
|
+
}
|
|
247
|
+
catch {
|
|
248
|
+
ws.send(JSON.stringify({ type: 'error', data: { message: 'Invalid JSON' } }));
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
// Send initial state
|
|
252
|
+
const requests = this.proxy.getRequests();
|
|
253
|
+
ws.send(JSON.stringify({
|
|
254
|
+
type: 'init',
|
|
255
|
+
data: requests,
|
|
256
|
+
}));
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Handle incoming WebSocket messages from the client.
|
|
261
|
+
*/
|
|
262
|
+
handleClientMessage(ws, msg) {
|
|
263
|
+
switch (msg.type) {
|
|
264
|
+
case 'ping':
|
|
265
|
+
ws.send(JSON.stringify({ type: 'pong', data: {} }));
|
|
266
|
+
break;
|
|
267
|
+
case 'subscribe':
|
|
268
|
+
ws.send(JSON.stringify({ type: 'subscribed', data: {} }));
|
|
269
|
+
break;
|
|
270
|
+
default:
|
|
271
|
+
break;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
setupProxyEvents() {
|
|
275
|
+
this.proxy.on('request', (req) => {
|
|
276
|
+
this.broadcast({
|
|
277
|
+
type: 'request',
|
|
278
|
+
data: req,
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
this.proxy.on('response', (req) => {
|
|
282
|
+
this.broadcast({
|
|
283
|
+
type: 'response',
|
|
284
|
+
data: req,
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
this.proxy.on('error', (err) => {
|
|
288
|
+
this.broadcast({
|
|
289
|
+
type: 'error',
|
|
290
|
+
data: { message: err.message },
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
broadcast(message) {
|
|
295
|
+
const data = JSON.stringify(message);
|
|
296
|
+
for (const client of this.clients) {
|
|
297
|
+
if (client.readyState === ws_1.WebSocket.OPEN) {
|
|
298
|
+
client.send(data);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
async start() {
|
|
303
|
+
return new Promise((resolve, reject) => {
|
|
304
|
+
this.httpServer
|
|
305
|
+
.listen(this.config.uiPort, '127.0.0.1', () => {
|
|
306
|
+
console.log(`UI Server listening on http://127.0.0.1:${this.config.uiPort}`);
|
|
307
|
+
resolve();
|
|
308
|
+
})
|
|
309
|
+
.on('error', reject);
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
stop() {
|
|
313
|
+
this.wss.close();
|
|
314
|
+
this.httpServer.close();
|
|
315
|
+
console.log('UI Server stopped');
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
exports.UIServer = UIServer;
|
|
319
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/ui/server.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "http-mitm-proxy-ui",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "HTTP MITM Proxy with a web-based UI for inspecting and modifying traffic",
|
|
5
|
+
"bin": {
|
|
6
|
+
"http-mitm-proxy-ui": "dist/index.js"
|
|
7
|
+
},
|
|
8
|
+
"main": "dist/index.js",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"patches",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "https://github.com/dungviettran89/http-mitm-proxy-ui"
|
|
17
|
+
},
|
|
18
|
+
"homepage": "https://github.com/dungviettran89/http-mitm-proxy-ui#readme",
|
|
19
|
+
"scripts": {
|
|
20
|
+
"test": "bash tests/integration-test.sh",
|
|
21
|
+
"build": "tsc && npx vite build --base ./",
|
|
22
|
+
"format": "prettier --write \"src/**/*.{ts,js}\" \"ui/src/**/*.{vue,ts,js,css}\"",
|
|
23
|
+
"format:check": "prettier --check \"src/**/*.{ts,js}\" \"ui/src/**/*.{vue,ts,js,css}\"",
|
|
24
|
+
"dev": "concurrently \"tsc -w\" \"vite dev --port 5173\"",
|
|
25
|
+
"start": "node dist/index.js",
|
|
26
|
+
"prepare": "npm run build",
|
|
27
|
+
"postinstall": "patch-package"
|
|
28
|
+
},
|
|
29
|
+
"keywords": [],
|
|
30
|
+
"author": "",
|
|
31
|
+
"license": "ISC",
|
|
32
|
+
"type": "commonjs",
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"commander": "^14.0.3",
|
|
35
|
+
"express": "^5.2.1",
|
|
36
|
+
"http-mitm-proxy": "^1.1.0",
|
|
37
|
+
"lowdb": "^7.0.1",
|
|
38
|
+
"patch-package": "^8.0.1",
|
|
39
|
+
"ws": "^8.18.0"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@playwright/test": "^1.59.1",
|
|
43
|
+
"@types/express": "^5.0.6",
|
|
44
|
+
"@types/node": "^25.5.2",
|
|
45
|
+
"@types/ws": "^8.18.1",
|
|
46
|
+
"@vitejs/plugin-vue": "^6.0.5",
|
|
47
|
+
"@vue/compiler-sfc": "^3.5.32",
|
|
48
|
+
"concurrently": "^9.2.0",
|
|
49
|
+
"flexsearch": "^0.8.212",
|
|
50
|
+
"prettier": "^3.8.1",
|
|
51
|
+
"typescript": "^6.0.2",
|
|
52
|
+
"vite": "^8.0.3",
|
|
53
|
+
"vue": "^3.5.32"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
diff --git a/node_modules/http-mitm-proxy/dist/lib/proxy.js b/node_modules/http-mitm-proxy/dist/lib/proxy.js
|
|
2
|
+
index e896595..d30ce5d 100644
|
|
3
|
+
--- a/node_modules/http-mitm-proxy/dist/lib/proxy.js
|
|
4
|
+
+++ b/node_modules/http-mitm-proxy/dist/lib/proxy.js
|
|
5
|
+
@@ -69,7 +69,7 @@ class Proxy {
|
|
6
|
+
const self = this;
|
|
7
|
+
this.options = options || {};
|
|
8
|
+
this.httpPort = options.port || options.port === 0 ? options.port : 8080;
|
|
9
|
+
- this.httpHost = options.host || "localhost";
|
|
10
|
+
+ this.httpHost = options.host || "127.0.0.1";
|
|
11
|
+
this.timeout = options.timeout || 0;
|
|
12
|
+
this.keepAlive = !!options.keepAlive;
|
|
13
|
+
this.httpAgent =
|
|
14
|
+
@@ -147,7 +147,7 @@ class Proxy {
|
|
15
|
+
});
|
|
16
|
+
const listenOptions = {
|
|
17
|
+
port: 0,
|
|
18
|
+
- host: "0.0.0.0",
|
|
19
|
+
+ host: "127.0.0.1",
|
|
20
|
+
};
|
|
21
|
+
if (this.httpsPort && !options.hosts) {
|
|
22
|
+
listenOptions.port = this.httpsPort;
|
|
23
|
+
@@ -361,7 +361,7 @@ class Proxy {
|
|
24
|
+
function makeConnection(port) {
|
|
25
|
+
const conn = net_1.default.connect({
|
|
26
|
+
port,
|
|
27
|
+
- host: "0.0.0.0",
|
|
28
|
+
+ host: "127.0.0.1",
|
|
29
|
+
allowHalfOpen: true,
|
|
30
|
+
}, () => {
|
|
31
|
+
const connectKey = `${conn.localPort}:${conn.remotePort}`;
|
|
32
|
+
diff --git a/node_modules/http-mitm-proxy/lib/proxy.ts b/node_modules/http-mitm-proxy/lib/proxy.ts
|
|
33
|
+
index 5a8154e..da79df7 100644
|
|
34
|
+
--- a/node_modules/http-mitm-proxy/lib/proxy.ts
|
|
35
|
+
+++ b/node_modules/http-mitm-proxy/lib/proxy.ts
|
|
36
|
+
@@ -216,7 +216,7 @@ export class Proxy implements IProxy {
|
|
37
|
+
// port 0 to get the first available port
|
|
38
|
+
const listenOptions = {
|
|
39
|
+
port: 0,
|
|
40
|
+
- host: "0.0.0.0",
|
|
41
|
+
+ host: "127.0.0.1",
|
|
42
|
+
};
|
|
43
|
+
if (this.httpsPort && !options.hosts) {
|
|
44
|
+
listenOptions.port = this.httpsPort;
|
|
45
|
+
@@ -487,7 +487,7 @@ export class Proxy implements IProxy {
|
|
46
|
+
const conn = net.connect(
|
|
47
|
+
{
|
|
48
|
+
port,
|
|
49
|
+
- host: "0.0.0.0",
|
|
50
|
+
+ host: "127.0.0.1",
|
|
51
|
+
allowHalfOpen: true,
|
|
52
|
+
},
|
|
53
|
+
|