PageSourceSearch

https://bluelanternsecurity.io/Integrations-Bafb01ve.js

js bluelanternsecurity.io collected 2026-10-02 01:57:40 UTC 117,037 bytes, 1 lines download raw bytes

1import{i as Z,r as n,j as e,c as ge,X as ae,C as oe,a5 as le,L as J,a6 as C,Z as he,d as Te,e as Me,f as c,I as ye,y as De,k as lt,a as it,_ as ot,P as ct,aj as pe,ak as Pe,al as Ce,a4 as ie}from"./index-C86sjUM7.js";import{b as Le,a as dt,p as xt,g as mt,c as ht,S as Fe,G as pt,i as qe,u as Oe,e as ue,f as ut,C as bt,h as ft,j as gt,k as yt,E as Ge,l as jt,m as Nt,n as wt,o as vt,q as Be,r as Ae,s as kt,t as St,v as Ct,w as At,d as _t,x as We,I as $e,y as Et,z as It,A as Rt,B as Tt,F as _e,M as Mt,D as Dt,H as Pt}from"./integrations-DtPDPoSE.js";import{U as be}from"./upload-Bgzkm4Dk.js";import{S as se}from"./shield-alert-cz1iZj9B.js";import{C as Ee}from"./clock-D-xVB89G.js";import{P as ze,A as Lt}from"./alertRules-CKtaJ58j.js";import{P as Ft}from"./plus-B1ssUL0Q.js";import{L as Ve}from"./lock-CAeLtCCS.js";import{C as je}from"./crosshair-CQNJkBVv.js";import{S as Ne}from"./shield-CqlVQTLX.js";import{R as Ie,T as Ue}from"./trash-2-C-9C-yvi.js";import{M as de}from"./mail-warning-Rw0pWsko.js";function te({value:a,label:t}){const[o,i]=n.useState(!1),l=()=>{navigator.clipboard.writeText(a),i(!0),setTimeout(()=>i(!1),1500)};return e.jsxs("div",{className:"flex items-center gap-2 rounded-lg border border-slate-800 bg-slate-950/70 px-3 py-2",children:[e.jsx("code",{className:"min-w-0 flex-1 break-all font-mono text-xs text-cyan-300",children:a}),e.jsx("button",{type:"button",onClick:l,className:"shrink-0 rounded-md p-1.5 text-slate-400 transition-colors hover:bg-slate-800 hover:text-white",title:`Copy ${t||"value"}`,"aria-label":`Copy ${t||"value"}`,children:o?e.jsx(Te,{className:"h-4 w-4 text-emerald-400"}):e.jsx(Me,{className:"h-4 w-4"})})]})}te.propTypes={value:c.string.isRequired,label:c.string};function ce({sync:a}){const t=dt(a);return t?e.jsxs("div",{className:"rounded-xl border border-slate-800 bg-slate-950/50 p-4 text-sm",children:[e.jsx("p",{className:"mb-2 font-semibold text-white",children:"Directory sync"}),e.jsxs("ul",{className:"space-y-1 text-slate-300",children:[e.jsxs("li",{children:[t.usersPulled," users pulled from your Workspace directory"]}),e.jsxs("li",{children:[t.seated," newly seated",t.upgradedToSeat>0?` · ${t.upgradedToSeat} existing members upgraded into a seat`:""]}),t.alreadyMembers>0&&e.jsxs("li",{children:[t.alreadyMembers," were already members (left untouched)"]}),t.mailboxesDeactivated>0&&e.jsxs("li",{children:[t.mailboxesDeactivated," mailboxes no longer in the directory were deactivated"]})]}),t.unmonitored>0&&e.jsxs("p",{className:"mt-3 flex items-start gap-1.5 text-amber-400/90",children:[e.jsx(C,{className:"mt-0.5 h-4 w-4 shrink-0"}),e.jsxs("span",{children:[t.unmonitored," users joined ",e.jsx("strong",{children:"unmonitored"})," — your seat plan (",t.seatCount," seats) is full. ",e.jsx(J,{to:"/organization",className:"underline hover:text-amber-300",children:"Add seats"})," ","and re-sync to monitor them."]})]})]}):null}ce.propTypes={sync:c.object};function we({endpoint:a,oidcServiceAccount:t,audience:o}){return e.jsxs("ol",{className:"space-y-4",children:[e.jsxs("li",{className:"flex gap-3",children:[e.jsx("span",{className:"flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-cyan-500/10 text-xs font-bold text-cyan-300 ring-1 ring-cyan-500/30",children:"1"}),e.jsxs("div",{className:"text-sm text-slate-300",children:[e.jsx("p",{className:"font-semibold text-white",children:"Create a Pub/Sub topic"}),e.jsxs("p",{className:"text-slate-400",children:["In the same Google Cloud project as your service account. The quickest way to reach it: type"," ",e.jsx("span",{className:"text-slate-300",children:"pub"})," into the search bar at the top of the console and pick"," ",e.jsx("span",{className:"text-slate-300",children:"Pub/Sub"})," (it is hard to find from the main menu)."]}),e.jsxs("p",{className:"mt-1 text-slate-400",children:["Topics → ",e.jsx("span",{className:"text-slate-300",children:"Create topic"})," → enter a Topic ID → ",e.jsx("span",{className:"text-slate-300",children:"Create"}),". The Topic ID can be anything you like (for example ",e.jsx("span",{className:"font-mono",children:"gmail-push"}),"); we never rely on a specific name. Leave every other option at its default."]})]})]}),e.jsxs("li",{className:"flex gap-3",children:[e.jsx("span",{className:"flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-cyan-500/10 text-xs font-bold text-cyan-300 ring-1 ring-cyan-500/30",children:"2"}),e.jsxs("div",{className:"min-w-0 flex-1 text-sm text-slate-300",children:[e.jsx("p",{className:"font-semibold text-white",children:"Let Gmail publish to it"}),e.jsxs("p",{className:"mb-2 text-slate-400",children:["In the Topics list, open the ",e.jsx("span",{className:"text-slate-300",children:"⋮"})," menu on the topic you just created →"," ",e.jsx("span",{className:"text-slate-300",children:"View permissions"})," → ",e.jsx("span",{className:"text-slate-300",children:"Add principal"}),". Paste this into ",e.jsx("span",{className:"text-slate-300",children:"New principals"})," (this is who Gmail publishes as):"]}),e.jsx(te,{value:pt,label:"Gmail publisher service account"}),e.jsxs("p",{className:"mt-2 text-slate-400",children:["In the ",e.jsx("span",{className:"text-slate-300",children:"Role"})," dropdown choose ",e.jsx("span",{className:"text-slate-300",children:"Pub/Sub Publisher"}),", then ",e.jsx("span",{className:"text-slate-300",children:"Save"}),"."]})]})]}),e.jsxs("li",{className:"flex gap-3",children:[e.jsx("span",{className:"flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-cyan-500/10 text-xs font-bold text-cyan-300 ring-1 ring-cyan-500/30",children:"3"}),e.jsxs("div",{className:"min-w-0 flex-1 text-sm text-slate-300",children:[e.jsx("p",{className:"font-semibold text-white",children:"Create a push subscription on the topic"}),e.jsxs("div",{className:"mt-2 space-y-3 text-slate-400",children:[e.jsxs("div",{children:[e.jsxs("p",{className:"mb-1",children:["Delivery type ",e.jsx("span",{className:"text-slate-300",children:"Push"})," · Endpoint URL:"]}),a?e.jsx(te,{value:a,label:"endpoint URL"}):e.jsx("p",{className:"text-xs text-slate-500",children:"Shown right after connecting."})]}),e.jsxs("div",{children:[e.jsxs("p",{className:"mb-1",children:[e.jsx("span",{className:"text-slate-300",children:"Enable authentication"}),", choosing your service account:"]}),t?e.jsx(te,{value:t,label:"service account"}):e.jsx("p",{className:"text-xs text-slate-500",children:"Shown right after connecting."})]}),e.jsxs("div",{children:[e.jsx("p",{className:"mb-1",children:"Audience:"}),o?e.jsx(te,{value:o,label:"audience"}):e.jsx("p",{className:"text-xs text-slate-500",children:"Shown right after connecting."})]})]})]})]})]})}we.propTypes={endpoint:c.string,oidcServiceAccount:c.string,audie
1nce:c.string};function Ke({integration:a,initialTopic:t,onSaved:o}){const{getValidToken:i}=Z(),[l,x]=n.useState(t||""),[g,y]=n.useState(!1),[T,h]=n.useState(null),[A,u]=n.useState(!1),E=async()=>{if(!qe(l)){h("Use the full topic name: projects/<your-project>/topics/<topic>.");return}y(!0),h(null);try{await Oe(i,{integrationId:a.id,settings:{pubsub_topic:l.trim()}}),u(!0),o?.()}catch(j){h(j.message||"Failed to save the topic.")}finally{y(!1)}};return e.jsxs("div",{children:[e.jsx("label",{className:"mb-2 block text-sm font-medium text-slate-300",children:"Your Pub/Sub topic"}),e.jsxs("div",{className:"flex flex-col gap-2 sm:flex-row",children:[e.jsx("input",{type:"text",value:l,onChange:j=>{x(j.target.value),u(!1)},placeholder:"projects/your-project/topics/bluelantern-gmail",spellCheck:!1,className:"min-w-0 flex-1 rounded-xl border border-slate-700 bg-slate-950 px-4 py-2.5 font-mono text-xs text-white placeholder:text-slate-600 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-cyan-500"}),e.jsx("button",{type:"button",onClick:E,disabled:g||!l.trim(),className:"inline-flex shrink-0 items-center justify-center gap-2 rounded-xl bg-cyan-600 px-4 py-2.5 text-sm font-semibold text-white transition-colors hover:bg-cyan-500 disabled:cursor-not-allowed disabled:opacity-50",children:g?"Saving…":A?"Saved":"Save Topic"})]}),T&&e.jsxs("p",{className:"mt-2 flex items-start gap-1.5 text-sm text-red-400",children:[e.jsx(C,{className:"mt-0.5 h-4 w-4 shrink-0"}),T]}),A&&e.jsxs("p",{className:"mt-2 flex items-center gap-1.5 text-sm text-emerald-400",children:[e.jsx(le,{className:"h-4 w-4"}),"Topic saved — mailbox watches arm automatically on the next daily sweep, then new mail flows into analysis."]})]})}Ke.propTypes={integration:c.object.isRequired,initialTopic:c.string,onSaved:c.func};const xe=["Before you start","Google Cloud","Workspace delegation","Connect"];function He({onClose:a,onConnected:t}){const{getValidToken:o}=Z(),[i,l]=n.useState(0),[x,g]=n.useState(!1),[y,T]=n.useState(""),[h,A]=n.useState(null),[u,E]=n.useState(""),[j,p]=n.useState(""),[b,d]=n.useState(!1),[S,w]=n.useState(null),[m,_]=n.useState(null);n.useEffect(()=>{const f=N=>{N.key==="Escape"&&!b&&a()};return window.addEventListener("keydown",f),()=>window.removeEventListener("keydown",f)},[a,b]);const K=f=>{T(f),A(f.trim()?xt(f):null)},M=f=>{const N=f.target.files?.[0];if(!N)return;const L=new FileReader;L.onload=()=>K(String(L.result||"")),L.readAsText(N),f.target.value=""},F=mt(x),D=()=>h?.ok?!u.trim()||!u.includes(".")?"Enter your Workspace primary domain (e.g. acme.com).":!j.trim()||!j.includes("@")?"Enter the email of a Workspace admin to impersonate.":null:"Go back to the Google Cloud step and provide the service account JSON key.",q=async()=>{const f=D();if(f){w(f);return}d(!0),w(null);try{const N=await ht(o,{serviceAccountKey:h.key,domain:u.trim(),impersonationAdmin:j.trim(),writeAccess:x});_(N),t()}catch(N){if(N.status===402&&N.reason===Fe){w("Gmail monitoring requires an active seat plan. Add seats from the Organization page, then run this connect flow again.");return}w(N.message||"Connection failed.")}finally{d(!1)}};return e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-slate-950/80 p-4 backdrop-blur-sm",onMouseDown:f=>{f.target===f.currentTarget&&!b&&a()},children:e.jsxs("div",{className:"flex max-h-[90vh] w-full max-w-2xl flex-col overflow-hidden rounded-2xl border border-slate-800 bg-slate-900 shadow-2xl",children:[e.jsxs("div",{className:"border-b border-slate-800 p-5 sm:p-6",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{children:[e.jsxs("h3",{className:"flex items-center gap-2 text-lg font-semibold text-white",children:[e.jsx(ge,{className:"h-5 w-5 text-cyan-400"}),"Connect Gmail (Google Workspace)"]}),e.jsxs("p",{className:"mt-1 text-sm text-slate-400",children:["One setup covers your whole org. Everything below happens in ",e.jsx("span",{className:"text-slate-300",children:"your"})," ","Google consoles — we never see your Google account."]})]}),e.jsx("button",{type:"button",onClick:a,"aria-label":"Close",className:"shrink-0 rounded-md p-1 text-slate-400 transition-colors hover:bg-slate-800 hover:text-white",children:e.jsx(ae,{className:"h-5 w-5"})})]}),!m&&e.jsx("ol",{className:"mt-4 flex flex-wrap items-center gap-2 text-xs",children:xe.map((f,N)=>e.jsxs("li",{className:"flex items-center gap-2",children:[e.jsxs("button",{type:"button",onClick:()=>l(N),className:`flex items-center gap-1.5 rounded-full border px-2.5 py-1 font-medium transition-colors ${N===i?"border-cyan-400/60 bg-cyan-400/10 text-cyan-300":"border-slate-700 bg-slate-950/60 text-slate-400 hover:border-slate-600"}`,children:[e.jsx("span",{className:"tabular-nums",children:N+1})," ",f]}),N<xe.length-1&&e.jsx(oe,{className:"h-3 w-3 text-slate-600"})]},f))})]}),e.jsx("div",{className:"space-y-5 overflow-y-auto p-5 sm:p-6",children:m?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-center gap-3 rounded-xl border border-emerald-500/20 bg-emerald-500/10 p-4 text-emerald-400",children:[e.jsx(le,{className:"h-5 w-5 shrink-0"}),e.jsx("span",{className:"font-medium",children:"Gmail connected — delegation validated and your directory was pulled."})]}),e.jsx(ce,{sync:m.sync}),e.jsxs("p",{className:"text-sm text-slate-400",children:["Pulled users appear on your ",e.jsx(J,{to:"/organization",className:"text-cyan-400 hover:text-cyan-300 hover:underline",children:"Organization page"}),"."]}),e.jsxs("div",{className:"rounded-xl border border-slate-800 bg-slate-950/40 p-4 sm:p-5",children:[e.jsx("p",{className:"mb-1 text-sm font-semibold text-white",children:"One more step: real-time mail delivery (Pub/Sub)"}),e.jsxs("p",{className:"mb-4 text-sm text-slate-400",children:["This is what makes Gmail send new mail to us for analysis automatically, within seconds of arrival. Back in ",e.jsx("span",{className:"text-slate-300",children:"your Google Cloud console"}),":"]}),e.jsx(we,{endpoint:Le(m.push_setup?.push_path),oidcServiceAccount:m.push_setup?.oidc_service_account,audience:m.push_setup?.oidc_audie
1nce}),e.jsxs("div",{className:"mt-4 border-t border-slate-800 pt-4",children:[m.integration?.id?e.jsx(Ke,{integration:m.integration,initialTopic:m.integration?.settings?.pubsub_topic||"",onSaved:t}):null,e.jsx("p",{className:"mt-3 text-xs text-slate-500",children:"No IP allowlist is needed on either side — the push subscription authenticates with a Google-signed token. You can finish this step any time later from the integration's Settings."})]})]}),e.jsx("div",{className:"flex justify-end border-t border-slate-800 pt-4",children:e.jsx("button",{type:"button",onClick:a,className:"rounded-lg bg-cyan-600 px-5 py-2 text-sm font-semibold text-white transition-colors hover:bg-cyan-500",children:"Done"})})]}):e.jsxs(e.Fragment,{children:[i===0&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"rounded-xl border border-slate-800 bg-slate-950/40 p-4 text-sm text-slate-300",children:[e.jsx("p",{className:"mb-2 font-semibold text-white",children:"You will need"}),e.jsxs("ul",{className:"list-disc space-y-1 pl-5 text-slate-400",children:[e.jsxs("li",{children:["Access to any ",e.jsx("span",{className:"text-slate-300",children:"Google Cloud project"})," your company owns (to create a service account)."]}),e.jsxs("li",{children:["A ",e.jsx("span",{className:"text-slate-300",children:"Google Workspace super admin"})," — only a super admin can grant domain-wide delegation. If that isn't you, you can still do the Google Cloud step and hand the delegation step to them."]}),e.jsx("li",{children:"About 10 minutes."})]})]}),e.jsxs("div",{children:[e.jsx("p",{className:"mb-2 text-sm font-semibold text-white",children:"Optional: spam-move action"}),e.jsxs("label",{className:"flex cursor-pointer items-start gap-3 rounded-xl border border-slate-700 bg-slate-950/60 p-4",children:[e.jsx("input",{type:"checkbox",checked:x,onChange:f=>g(f.target.checked),className:"mt-0.5 h-4 w-4 accent-cyan-500"}),e.jsxs("span",{className:"text-sm text-slate-300",children:["Let Blue Lantern ",e.jsx("span",{className:"text-white",children:"move detected phishing to Spam"})," automatically.",e.jsx("span",{className:"block pt-1 text-slate-500",children:"This adds one write scope (gmail.modify) to the delegation grant in step 3. Leave it off for strictly read-only access — you can enable it later, but that requires re-granting and re-running this connect flow."})]})]})]}),e.jsxs("div",{className:"rounded-xl border border-cyan-500/20 bg-cyan-500/5 p-4 text-xs text-slate-400",children:[e.jsx("p",{className:"mb-1 font-semibold text-cyan-300",children:"How your credentials are handled"}),"The service-account key is sent once over TLS and stored in AWS Secrets Manager — never in our database, and never returned by any API. Access is ",x?"read-only except the spam-move action you enabled":"strictly read-only",", and you can revoke the delegation at any time in your Workspace admin console."]})]}),i===1&&e.jsxs(e.Fragment,{children:[e.jsxs("p",{className:"text-sm text-slate-400",children:["In ",e.jsx("span",{className:"text-slate-300",children:"Google Cloud console"})," (any project your company owns):"]}),e.jsxs("ol",{className:"space-y-4",children:[e.jsxs("li",{className:"flex gap-3",children:[e.jsx("span",{className:"flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-cyan-500/10 text-xs font-bold text-cyan-300 ring-1 ring-cyan-500/30",children:"1"}),e.jsxs("div",{className:"text-sm text-slate-300",children:[e.jsx("p",{className:"font-semibold text-white",children:"Enable two APIs"}),e.jsxs("p",{className:"text-slate-400",children:["APIs & Services → Library → enable ",e.jsx("span",{className:"text-slate-300",children:"Admin SDK API"})," and ",e.jsx("span",{className:"text-slate-300",children:"Gmail API"}),"."]})]})]}),e.jsxs("li",{className:"flex gap-3",children:[e.jsx("span",{className:"flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-cyan-500/10 text-xs font-bold text-cyan-300 ring-1 ring-cyan-500/30",children:"2"}),e.jsxs("div",{className:"text-sm text-slate-300",children:[e.jsx("p",{className:"font-semibold text-white",children:"Create a service account"}),e.jsx("p",{className:"text-slate-400",children:"IAM & Admin → Service Accounts → Create. No project roles or permissions are needed — its authority comes from the delegation you grant in the next step, not from IAM."})]})]}),e.jsxs("li",{className:"flex gap-3",children:[e.jsx("span",{className:"flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-cyan-500/10 text-xs font-bold text-cyan-300 ring-1 ring-cyan-500/30",children:"3"}),e.jsxs("div",{className:"text-sm text-slate-300",children:[e.jsx("p",{className:"font-semibold text-white",children:"Create and download a JSON key"}),e.jsxs("p",{className:"text-slate-400",children:["Open the service account → Keys → Add key → Create new key → ",e.jsx("span",{className:"text-slate-300",children:"JSON"}),". A key file downloads — provide it below."]})]})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"mb-2 flex items-center justify-between gap-2",children:[e.jsx("label",{className:"text-sm font-medium text-slate-300",children:"Service account JSON key"}),e.jsxs("label",{className:"inline-flex cursor-pointer items-center gap-1.5 rounded-lg border border-slate-700 bg-slate-950/60 px-3 py-1.5 text-xs font-medium text-slate-300 transition-colors hover:border-slate-600 hover:text-white",children:[e.jsx(be,{className:"h-3.5 w-3.5"}),"Upload file",e.jsx("input",{type:"file",accept:".json,application/json",onChange:M,className:"hidden"})]})]}),e.jsx("textarea",{value:y,onChange:f=>K(f.target.value),rows:5,placeholder:'{"type": "service_account", "project_id": …}',spellCheck:!1,className:"w-full rounded-xl border border-slate-700 bg-slate-950 px-4 py-3 font-mono text-xs text-white placeholder:text-slate-600 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-cyan-500"}),h&&!h.ok&&e.jsxs("p",{className:"mt-2 flex items-start gap-1.5 text-sm text-red-400",children:[e.jsx(C,{className:"mt-0.5 h-4 w-4 shrink-0"}),h.error]}),h?.ok&&e.jsxs("div",{className:"mt-2 space-y-1 text-xs text-slate-400",children:[e.jsxs("p",{className:"flex items-center gap-1.5 text-emerald-400",children:[e.jsx(le,{className:"h-3.5 w-3.5"})," Key looks valid: ",e.jsx("span",{className:"font-mono",children:h.clientEmail})]}),e.jsx("p",{children:"Its client ID (needed in the next step) is shown there automatically."})]})]})]}),i===2&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-start gap-2 rounded-lg border border-amber-500/20 bg-amber-500/5 px-3 py-2 text-xs text-amber-400/90",children:[e.jsx(C,{className:"mt-0.5 h-3.5 w-3.5 shrink-0"}
1),"This step requires a ",e.jsx("strong",{children:"Workspace super admin"}),". If that isn't you, send them the client ID and scopes below."]}),e.jsxs("p",{className:"text-sm text-slate-400",children:["In the ",e.jsx("span",{className:"text-slate-300",children:"Google Workspace Admin console"})," (admin.google.com):"]}),e.jsxs("ol",{className:"space-y-4",children:[e.jsxs("li",{className:"flex gap-3",children:[e.jsx("span",{className:"flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-cyan-500/10 text-xs font-bold text-cyan-300 ring-1 ring-cyan-500/30",children:"1"}),e.jsxs("div",{className:"text-sm text-slate-300",children:[e.jsx("p",{className:"font-semibold text-white",children:"Open domain-wide delegation"}),e.jsxs("p",{className:"text-slate-400",children:["Security → Access and data control → API controls → ",e.jsx("span",{className:"text-slate-300",children:"Domain-wide delegation"})," → Add new."]})]})]}),e.jsxs("li",{className:"flex gap-3",children:[e.jsx("span",{className:"flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-cyan-500/10 text-xs font-bold text-cyan-300 ring-1 ring-cyan-500/30",children:"2"}),e.jsxs("div",{className:"min-w-0 flex-1 text-sm text-slate-300",children:[e.jsx("p",{className:"font-semibold text-white",children:"Client ID"}),e.jsxs("p",{className:"mb-2 text-slate-400",children:["The service account's numeric client ID (the ",e.jsx("span",{className:"font-mono",children:"client_id"})," field in the JSON key; also on the service account's details page)."]}),h?.ok?e.jsx(te,{value:h.clientId,label:"client ID"}):e.jsx("p",{className:"text-xs text-slate-500",children:"Provide the key in the previous step and your client ID appears here for copy-paste."})]})]}),e.jsxs("li",{className:"flex gap-3",children:[e.jsx("span",{className:"flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-cyan-500/10 text-xs font-bold text-cyan-300 ring-1 ring-cyan-500/30",children:"3"}),e.jsxs("div",{className:"min-w-0 flex-1 text-sm text-slate-300",children:[e.jsx("p",{className:"font-semibold text-white",children:"OAuth scopes"}),e.jsxs("p",{className:"mb-2 text-slate-400",children:["Paste as one comma-separated line (",F.length," scope",F.length>1?"s":"",x?", including the write scope for spam-move":", read-only","):"]}),e.jsx(te,{value:F.join(","),label:"scopes"}),!x&&e.jsxs("p",{className:"mt-2 text-xs text-slate-500",children:["Enabling the spam-move action later requires adding ",e.jsx("span",{className:"font-mono",children:"gmail.modify"})," here and re-running this connect flow."]})]})]})]})]}),i===3&&e.jsxs(e.Fragment,{children:[S&&e.jsxs("div",{className:"flex items-start gap-3 rounded-xl border border-red-500/20 bg-red-500/10 p-4 text-red-400",children:[e.jsx(C,{className:"mt-0.5 h-5 w-5 shrink-0"}),e.jsx("span",{className:"text-sm",children:S})]}),e.jsxs("p",{className:"text-sm text-slate-400",children:["Last step — we validate the delegation ",e.jsx("span",{className:"text-slate-300",children:"live"})," (a directory list and a mailbox read, impersonating the admin below) before anything is stored."]}),e.jsxs("div",{children:[e.jsx("label",{className:"mb-2 block text-sm font-medium text-slate-300",children:"Workspace primary domain"}),e.jsx("input",{type:"text",value:u,onChange:f=>E(f.target.value),placeholder:"acme.com",className:"w-full rounded-xl border border-slate-700 bg-slate-950 px-4 py-3 font-mono text-sm text-white placeholder:text-slate-600 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-cyan-500"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"mb-2 block text-sm font-medium text-slate-300",children:"Admin to impersonate"}),e.jsx("input",{type:"email",value:j,onChange:f=>p(f.target.value),placeholder:"[email protected]",className:"w-full rounded-xl border border-slate-700 bg-slate-950 px-4 py-3 font-mono text-sm text-white placeholder:text-slate-600 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-cyan-500"}),e.jsx("p",{className:"mt-2 text-sm text-slate-500",children:"A Workspace admin's email — used for directory reads via the delegation, nothing more."})]}),e.jsxs("div",{className:"rounded-xl border border-slate-800 bg-slate-950/40 p-4 text-sm text-slate-400",children:[e.jsx("p",{className:"mb-1 font-semibold text-white",children:"Summary"}),e.jsxs("ul",{className:"space-y-1",children:[e.jsxs("li",{children:["Key: ",h?.ok?e.jsx("span",{className:"font-mono text-xs text-emerald-400",children:h.clientEmail}):e.jsx("span",{className:"text-red-400",children:"missing — go back to step 2"})]}),e.jsxs("li",{children:["Access: ",x?"read-only + spam-move (gmail.modify)":"strictly read-only"]})]})]})]}),e.jsxs("div",{className:"flex items-center justify-between gap-3 border-t border-slate-800 pt-4",children:[e.jsxs("button",{type:"button",onClick:()=>i===0?a():l(i-1),disabled:b,className:"inline-flex items-center gap-1.5 rounded-lg px-4 py-2 text-sm font-medium text-slate-400 transition-colors hover:bg-slate-800 hover:text-white disabled:opacity-50",children:[e.jsx(he,{className:"h-4 w-4"}),i===0?"Cancel":"Back"]}),i<xe.length-1?e.jsxs("button",{type:"button",onClick:()=>l(i+1),className:"inline-flex items-center gap-1.5 rounded-lg bg-cyan-600 px-5 py-2 text-sm font-semibold text-white transition-colors hover:bg-cyan-500",children:["Next",e.jsx(oe,{className:"h-4 w-4"})]}):e.jsx("button",{type:"button",onClick:q,disabled:b,className:"inline-flex items-center gap-2 rounded-lg bg-cyan-600 px-5 py-2 text-sm font-semibold text-white transition-colors hover:bg-cyan-500 disabled:cursor-not-allowed disabled:opacity-50",children:b?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"h-4 w-4 animate-spin rounded-full border-2 border-white/30 border-t-white"}),"Validating delegation…"]}):"Connect Gmail"})]})]})})]})})}
1He.propTypes={onClose:c.func.isRequired,onConnected:c.func.isRequired};function ne({value:a,label:t,mono:o=!0}){const[i,l]=n.useState(!1),x=()=>{navigator.clipboard.writeText(a),l(!0),setTimeout(()=>l(!1),1500)};return e.jsx("div",{className:"rounded-lg border border-slate-800 bg-slate-950/70",children:e.jsxs("div",{className:"flex items-start gap-2 p-2",children:[e.jsx("pre",{className:`min-w-0 flex-1 overflow-x-auto whitespace-pre-wrap break-all p-1 text-xs leading-relaxed text-cyan-300 ${o?"font-mono":""}`,children:a}),e.jsx("button",{type:"button",onClick:x,className:"shrink-0 rounded-md p-1.5 text-slate-400 transition-colors hover:bg-slate-800 hover:text-white",title:`Copy ${t||"value"}`,"aria-label":`Copy ${t||"value"}`,children:i?e.jsx(Te,{className:"h-4 w-4 text-emerald-400"}):e.jsx(Me,{className:"h-4 w-4"})})]})})}ne.propTypes={value:c.string.isRequired,label:c.string,mono:c.bool};function ve({scopeCheck:a}){const t=Be(a);if(!t)return null;const o=t.tone==="ok";return e.jsxs("div",{className:`flex items-start gap-3 rounded-xl border p-4 text-sm ${o?"border-emerald-500/20 bg-emerald-500/10":"border-amber-500/20 bg-amber-500/5"}`,children:[o?e.jsx(De,{className:"mt-0.5 h-5 w-5 shrink-0 text-emerald-400"}):e.jsx(se,{className:"mt-0.5 h-5 w-5 shrink-0 text-amber-400"}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("p",{className:`font-semibold ${o?"text-emerald-400":"text-amber-300"}`,children:t.label}),e.jsx("p",{className:"mt-1 break-words text-slate-400",children:a?.message||t.detail})]})]})}ve.propTypes={scopeCheck:c.oneOfType([c.object,c.string])};function ke({onAccept:a,busy:t}){const[o,i]=n.useState(!1);return o?e.jsxs("div",{className:"rounded-xl border border-amber-500/30 bg-amber-500/5 p-4 text-sm",children:[e.jsx("p",{className:"font-semibold text-amber-300",children:"Connect with tenant-wide access?"}),e.jsxs("p",{className:"mt-1 text-slate-300",children:["The credential will be able to read ",e.jsx("span",{className:"text-white",children:"any mailbox in your tenant"}),", not just the monitored group. Your acknowledgement is recorded with your name and the time."]}),e.jsxs("p",{className:"mt-2 text-xs text-slate-400",children:["What this does and does not change: the monitored group still decides ",e.jsx("span",{className:"text-slate-300",children:"who we analyze"})," — seat assignment reads it, and our ingest worker refuses any mailbox without a seat regardless of Exchange. This widens the credential's reach, not the mail we process. You can add the policy later and re-verify."]}),e.jsxs("div",{className:"mt-3 flex flex-wrap items-center gap-3",children:[e.jsx("button",{type:"button",onClick:a,disabled:t,className:"inline-flex shrink-0 items-center gap-2 whitespace-nowrap rounded-lg bg-amber-600 px-4 py-2 text-xs font-semibold text-white transition-colors hover:bg-amber-500 disabled:cursor-not-allowed disabled:opacity-50",children:t?"Connecting…":"I understand — connect anyway"}),e.jsx("button",{type:"button",onClick:()=>i(!1),disabled:t,className:"text-xs font-medium text-slate-400 transition-colors hover:text-slate-200 disabled:opacity-50",children:"Cancel"})]})]}):e.jsx("button",{type:"button",onClick:()=>i(!0),className:"text-xs font-medium text-slate-400 underline transition-colors hover:text-slate-200",children:"Connect without an access policy instead"})}ke.propTypes={onAccept:c.func.isRequired,busy:c.bool};function qt(a){const[t,o]=n.useState(a??0);return n.useEffect(()=>{o(a??0)},[a]),n.useEffect(()=>{if(t<=0)return;const i=setInterval(()=>{o(l=>l<=1?0:l-1)},1e3);return()=>clearInterval(i)},[t]),t}function Se({pending:a,onVerified:t,onRefresh:o,compact:i=!1}){const{getValidToken:l}=Z(),[x,g]=n.useState(!1),[y,T]=n.useState(null),[h,A]=n.useState(null),[u,E]=n.useState(a?.retry_after_seconds??0),j=qt(u),p=y||a,b=ue(p?.reason),d=b?.evidenceField?p?.scope_check?.[b.evidenceField]:null,S=p?.scope_check?.policy_block===!0,w=async(m=!1)=>{g(!0),A(null);try{const _=await Ct(l,{acceptUnrestrictedAccess:m});if(_.httpStatus===200){t?.(_);return}T(_),E(_.retry_after_seconds??0),o?.()}catch(_){_.status===429?(E(_.retryAfterSeconds??0),A(_.message||"Too soon to verify again — wait for the countdown.")):A(_.message||"Verification failed.")}finally{g(!1)}};return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-start gap-3 rounded-xl border border-amber-500/20 bg-amber-500/5 p-4",children:[e.jsx(Ee,{className:"mt-0.5 h-5 w-5 shrink-0 text-amber-400"}),e.jsxs("div",{className:"min-w-0 flex-1 text-sm",children:[e.jsxs("p",{className:"font-semibold text-amber-300",children:["Saved as pending",b?` — ${b.title.toLowerCase()}`:""]}),e.jsxs("p",{className:"mt-1 text-slate-300",children:["Your configuration and credential are saved, so nothing needs re-entering. Until the scope proof passes this integration is ",e.jsx("span",{className:"text-white",children:"inert"}),": no mailbox is read, no seat is assigned, and no subscription is created."]}),p?.message&&e.jsx("p",{className:"mt-2 break-words rounded-lg border border-slate-800 bg-slate-950/60 p-3 text-slate-300",children:p.message}),d&&e.jsxs("p",{className:"mt-2 break-words text-xs text-slate-400",children:[b.evidenceLabel,": ",e.jsx("span",{className:"break-all font-mono text-slate-300",children:d})]}),S&&e.jsx("p",{className:"mt-2 break-words text-xs text-amber-400/90",children:Ge})]})]}),h&&e.jsxs("p",{className:"flex items-start gap-1.5 text-sm text-red-400",children:[e.jsx(C,{className:"mt-0.5 h-4 w-4 shrink-0"}),e.jsx("span",{className:"min-w-0 break-words",children:h})]}),e.jsxs("div",{className:`flex flex-wrap items-center gap-3 ${i?"":"border-t border-slate-800 pt-4"}`,children:[e.jsx("button",{type:"button",onClick:()=>w(!1),disabled:x||j>0,className:"inline-flex shrink-0 items-center gap-2 whitespace-nowrap rounded-lg bg-cyan-600 px-5 py-2 text-sm font-semibold text-white transition-colors hover:bg-cyan-500 disabled:cursor-not-allowed disabled:opacity-50",children:x?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"h-4 w-4 animate-spin rounded-full border-2 border-white/30 border-t-white"}),"Verifying…"]}):j>0?e.jsxs(e.Fragment,{children:[e.jsx(Ee,{className:"h-4 w-4"}),"Verify in ",wt(j)]}
1):"Verify now"}),j>0&&e.jsx("span",{className:"min-w-0 flex-1 text-xs text-slate-500",children:"Verifying sooner would reset the wait — the button enables itself when it is safe to try."})]}),vt(p?.reason)&&e.jsx(ke,{onAccept:()=>w(!0),busy:x})]})}Se.propTypes={pending:c.object,onVerified:c.func,onRefresh:c.func,compact:c.bool};const me=["Before you start","Entra app","Scope (recommended)","Connect"];function Ye({onClose:a,onConnected:t}){const{getValidToken:o}=Z(),[i,l]=n.useState(0),[x,g]=n.useState(!1),[y,T]=n.useState(""),[h,A]=n.useState(""),[u,E]=n.useState("certificate"),[j,p]=n.useState(""),[b,d]=n.useState(""),[S,w]=n.useState(""),[m,_]=n.useState(""),[K,M]=n.useState(""),[F,D]=n.useState(""),[q,f]=n.useState(""),[N,L]=n.useState(!1),[W,O]=n.useState(null),[$,X]=n.useState(null),[G,H]=n.useState(null),[Q,Y]=n.useState(null);n.useEffect(()=>{const s=k=>{k.key==="Escape"&&!N&&a()};return window.addEventListener("keydown",s),()=>window.removeEventListener("keydown",s)},[a,N]);const U=jt(x),R=()=>u==="certificate"?kt({privateKey:j,certificate:b}):St({value:S,expiresAt:m}),P=()=>{if(!Ae.test(y.trim()))return"Enter the Directory (tenant) ID from Entra — it is a GUID.";if(!Ae.test(h.trim()))return"Enter the Application (client) ID from Entra — it is a GUID.";const s=R();return s.ok?q.trim()?null:"Enter the monitored security group (mail address or object id) from the previous step.":s.error},z=async(s=!1)=>{const k=P();if(k){O(k),X(null);return}L(!0),O(null),X(null);try{const v=await Nt(o,{tenantId:y.trim(),clientId:h.trim(),credential:R().credential,monitoredGroup:q.trim(),writeAccess:x,acceptUnrestrictedAccess:s});v.httpStatus===202||v.status==="pending"?Y(v):H(v),t()}catch(v){v.status===402&&v.reason===Fe?O("Outlook monitoring requires an active seat plan. Add seats from the Organization page, then run this connect flow again."):v.status===403&&ue(v.reason)?(O(v.message||null),X({reason:v.reason,scopeCheck:v.scopeCheck})):O(v.message||"Connection failed.")}finally{L(!1)}},I=$?ue($.reason):null,ee=I?.evidenceField?$?.scopeCheck?.[I.evidenceField]:null,re=$?.scopeCheck?.policy_block===!0;return e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-slate-950/80 p-4 backdrop-blur-sm",onMouseDown:s=>{s.target===s.currentTarget&&!N&&a()},children:e.jsxs("div",{className:"flex max-h-[90vh] w-full max-w-2xl flex-col overflow-hidden rounded-2xl border border-slate-800 bg-slate-900 shadow-2xl",children:[e.jsxs("div",{className:"border-b border-slate-800 p-5 sm:p-6",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{children:[e.jsxs("h3",{className:"flex items-center gap-2 text-lg font-semibold text-white",children:[e.jsx(ye,{className:"h-5 w-5 text-cyan-400"}),"Connect Microsoft 365 / Outlook"]}),e.jsxs("p",{className:"mt-1 text-sm text-slate-400",children:["The app registration lives in ",e.jsx("span",{className:"text-slate-300",children:"your"})," tenant — we never hold your Microsoft credentials, and you can revoke access at any time."]})]}),e.jsx("button",{type:"button",onClick:a,"aria-label":"Close",className:"shrink-0 rounded-md p-1 text-slate-400 transition-colors hover:bg-slate-800 hover:text-white",children:e.jsx(ae,{className:"h-5 w-5"})})]}),!G&&e.jsx("ol",{className:"mt-4 flex flex-wrap items-center gap-2 text-xs",children:me.map((s,k)=>e.jsxs("li",{className:"flex items-center gap-2",children:[e.jsxs("button",{type:"button",onClick:()=>l(k),className:`flex items-center gap-1.5 rounded-full border px-2.5 py-1 font-medium transition-colors ${k===i?"border-cyan-400/60 bg-cyan-400/10 text-cyan-300":"border-slate-700 bg-slate-950/60 text-slate-400 hover:border-slate-600"}`,children:[e.jsx("span",{className:"tabular-nums",children:k+1})," ",s]}),k<me.length-1&&e.jsx(oe,{className:"h-3 w-3 text-slate-600"})]},s))})]}),e.jsx("div",{className:"space-y-5 overflow-y-auto p-5 sm:p-6",children:Q?e.jsxs(e.Fragment,{children:[e.jsx(Se,{pending:Q,onVerified:s=>{Y(null),H(s),t()},onRefresh:t}),e.jsx("div",{className:"flex justify-end border-t border-slate-800 pt-4",children:e.jsx("button",{type:"button",onClick:a,className:"rounded-lg border border-slate-700 bg-slate-900/60 px-5 py-2 text-sm font-semibold text-slate-200 transition-colors hover:border-slate-600 hover:text-white",children:"Close and verify later"})})]}):G?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-center gap-3 rounded-xl border border-emerald-500/20 bg-emerald-500/10 p-4 text-emerald-400",children:[e.jsx(le,{className:"h-5 w-5 shrink-0"}),e.jsx("span",{className:"font-medium",children:"Outlook connected — access verified and your directory was pulled."})]}),e.jsx(ve,{scopeCheck:G.scope_check}),e.jsx(ce,{sync:G.sync}),e.jsxs("p",{className:"text-sm text-slate-400",children:["Seated users appear on your ",e.jsx(J,{to:"/organization",className:"text-cyan-400 hover:text-cyan-300 hover:underline",children:"Organization page"}),". Mail subscriptions are created automatically — no further setup in Microsoft is required, and new mail begins flowing into analysis shortly."]}),G.integration?.credential_expires_at&&e.jsxs("p",{className:"rounded-lg border border-slate-800 bg-slate-950/40 px-3 py-2 text-xs text-slate-400",children:["Your credential expires on"," ",e.jsx("span",{className:"text-slate-300",children:new Date(G.integration.credential_expires_at).toLocaleDateString()}
1),". We warn you before it lapses — an expired credential silently stops monitoring."]}),e.jsx("div",{className:"flex justify-end border-t border-slate-800 pt-4",children:e.jsx("button",{type:"button",onClick:a,className:"rounded-lg bg-cyan-600 px-5 py-2 text-sm font-semibold text-white transition-colors hover:bg-cyan-500",children:"Done"})})]}):e.jsxs(e.Fragment,{children:[i===0&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"rounded-xl border border-slate-800 bg-slate-950/40 p-4 text-sm text-slate-300",children:[e.jsx("p",{className:"mb-2 font-semibold text-white",children:"You will need"}),e.jsxs("ul",{className:"list-disc space-y-1 pl-5 text-slate-400",children:[e.jsxs("li",{children:["An ",e.jsx("span",{className:"text-slate-300",children:"Entra ID administrator"})," who can register an app and grant admin consent."]}),e.jsxs("li",{children:[e.jsx("span",{className:"text-slate-300",children:"Optionally"}),", an Exchange administrator to run a short PowerShell script that narrows which mailboxes the credential can read (recommended)."]}),e.jsx("li",{children:"About 15 minutes."})]})]}),e.jsxs("div",{className:"flex items-start gap-2 rounded-lg border border-amber-500/20 bg-amber-500/5 px-3 py-2 text-xs text-amber-400/90",children:[e.jsx(se,{className:"mt-0.5 h-3.5 w-3.5 shrink-0"}),e.jsxs("span",{children:[e.jsx("strong",{children:"About mailbox scope."})," Microsoft application permissions grant access to"," ",e.jsx("strong",{children:"every mailbox in your tenant"})," by default. The optional access policy in step 3 narrows the credential to a group you choose, and we verify whether it is enforced. It is recommended but not required — you can connect without it and we will record that choice. Either way, only ",e.jsx("strong",{children:"seated members"})," ","are analyzed; that limit lives in our ingest worker, not in Exchange."]})]}),e.jsxs("div",{children:[e.jsx("p",{className:"mb-2 text-sm font-semibold text-white",children:"Optional: auto-quarantine"}),e.jsxs("label",{className:"flex cursor-pointer items-start gap-3 rounded-xl border border-slate-700 bg-slate-950/60 p-4",children:[e.jsx("input",{type:"checkbox",checked:x,onChange:s=>g(s.target.checked),className:"mt-0.5 h-4 w-4 accent-cyan-500"}),e.jsxs("span",{className:"text-sm text-slate-300",children:["Let Blue Lantern ",e.jsx("span",{className:"text-white",children:"move detected phishing to the Junk Email folder"}),".",e.jsx("span",{className:"block pt-1 text-slate-500",children:"This adds the Mail.ReadWrite permission in the next step. Leave it off for read-only access — enabling it later means re-consenting and re-running this flow."})]})]})]})]}),i===1&&e.jsxs(e.Fragment,{children:[e.jsxs("p",{className:"text-sm text-slate-400",children:["In the ",e.jsx("span",{className:"text-slate-300",children:"Microsoft Entra admin center"}),":"]}),e.jsxs("ol",{className:"space-y-4",children:[e.jsxs("li",{className:"flex gap-3",children:[e.jsx("span",{className:"flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-cyan-500/10 text-xs font-bold text-cyan-300 ring-1 ring-cyan-500/30",children:"1"}),e.jsxs("div",{className:"text-sm text-slate-300",children:[e.jsx("p",{className:"font-semibold text-white",children:"Register an app"}),e.jsxs("p",{className:"text-slate-400",children:["App registrations → New registration → ",e.jsx("span",{className:"text-slate-300",children:"single tenant"}),'. Name it anything (e.g. "Blue Lantern Monitoring").']})]})]}),e.jsxs("li",{className:"flex gap-3",children:[e.jsx("span",{className:"flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-cyan-500/10 text-xs font-bold text-cyan-300 ring-1 ring-cyan-500/30",children:"2"}),e.jsxs("div",{className:"min-w-0 flex-1 text-sm text-slate-300",children:[e.jsx("p",{className:"font-semibold text-white",children:"Add application permissions, then grant admin consent"}),e.jsxs("p",{className:"mb-2 text-slate-400",children:["API permissions → Microsoft Graph → ",e.jsx("span",{className:"text-slate-300",children:"Application permissions"})," (not delegated) → add:"]}),e.jsx("ul",{className:"mb-2 space-y-1 font-mono text-xs text-cyan-300/90",children:U.map(s=>e.jsxs("li",{children:[s,s==="Mail.ReadWrite"&&e.jsx("span",{className:"font-sans text-slate-500",children:" (auto-quarantine)"}),s==="User.Read.All"&&e.jsx("span",{className:"font-sans text-slate-500",children:" (directory)"}),s==="GroupMember.Read.All"&&e.jsx("span",{className:"font-sans text-slate-500",children:" (resolve the monitored group)"})]},s))}),e.jsxs("p",{className:"text-slate-400",children:["Then click ",e.jsx("span",{className:"text-slate-300",children:"Grant admin consent"})," — without it every mailbox read fails."]}),e.jsx("p",{className:"mt-2 text-slate-400",children:"Planning to use the optional daily posture scans? Add these now to avoid a re-consent later — they stay unused until you enable the checks in Settings:"}),e.jsxs("ul",{className:"mt-1 space-y-1 font-mono text-xs text-cyan-300/90",children:[e.jsxs("li",{children:["AuditLog.Read.All ",e.jsx("span",{className:"font-sans text-slate-500",children:"(MFA + dormancy checks;
1 dormancy also needs an Entra ID P1/P2 license)"})]}),e.jsxs("li",{children:["MailboxSettings.Read ",e.jsx("span",{className:"font-sans text-slate-500",children:"(auto-forwarding + inbox-rule checks)"})]})]})]})]}),e.jsxs("li",{className:"flex gap-3",children:[e.jsx("span",{className:"flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-cyan-500/10 text-xs font-bold text-cyan-300 ring-1 ring-cyan-500/30",children:"3"}),e.jsxs("div",{className:"min-w-0 flex-1 text-sm text-slate-300",children:[e.jsx("p",{className:"font-semibold text-white",children:"Allow notification tokens"}),e.jsxs("p",{className:"text-slate-400",children:["Enterprise applications → your app → Properties → set"," ",e.jsx("span",{className:"text-slate-300",children:'"Assignment required?"'})," to ",e.jsx("span",{className:"text-slate-300",children:"No"}),". Microsoft only signs the notifications we require when this is set. If your tenant policy forbids it, assign this service principal a role on the app instead:"]}),e.jsx("div",{className:"mt-2",children:e.jsx(ne,{value:ut,label:"Graph Change Tracking service principal"})})]})]}),e.jsxs("li",{className:"flex gap-3",children:[e.jsx("span",{className:"flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-cyan-500/10 text-xs font-bold text-cyan-300 ring-1 ring-cyan-500/30",children:"4"}),e.jsxs("div",{className:"text-sm text-slate-300",children:[e.jsx("p",{className:"font-semibold text-white",children:"Create a credential"}),e.jsxs("p",{className:"text-slate-400",children:["Certificates & secrets → upload a ",e.jsx("span",{className:"text-slate-300",children:"certificate"})," (preferred — we read its expiry directly) or create a ",e.jsx("span",{className:"text-slate-300",children:"client secret"})," and note its expiry date. Collect these below along with the Directory (tenant) ID and Application (client) ID from the app's Overview page."]})]})]})]}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsxs("div",{children:[e.jsx("label",{className:"mb-2 block text-sm font-medium text-slate-300",children:"Directory (tenant) ID"}),e.jsx("input",{type:"text",value:y,onChange:s=>T(s.target.value),placeholder:"00000000-0000-0000-0000-000000000000",spellCheck:!1,className:"w-full rounded-xl border border-slate-700 bg-slate-950 px-4 py-2.5 font-mono text-xs text-white placeholder:text-slate-600 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-cyan-500"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"mb-2 block text-sm font-medium text-slate-300",children:"Application (client) ID"}),e.jsx("input",{type:"text",value:h,onChange:s=>A(s.target.value),placeholder:"00000000-0000-0000-0000-000000000000",spellCheck:!1,className:"w-full rounded-xl border border-slate-700 bg-slate-950 px-4 py-2.5 font-mono text-xs text-white placeholder:text-slate-600 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-cyan-500"})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"mb-2 block text-sm font-medium text-slate-300",children:"Credential"}),e.jsx("div",{className:"mb-3 grid grid-cols-2 gap-2",children:[{value:"certificate",label:"Certificate"},{value:"secret",label:"Client secret"}].map(s=>e.jsxs("button",{type:"button",onClick:()=>E(s.value),className:`rounded-xl border px-3 py-2.5 text-sm font-medium transition-colors ${u===s.value?"border-cyan-400/60 bg-cyan-400/10 text-cyan-300":"border-slate-700 bg-slate-950/60 text-slate-400 hover:border-slate-600"}`,children:[s.label,s.value==="certificate"&&e.jsx("span",{className:"block text-[11px] font-normal text-slate-500",children:"Preferred"}),s.value==="secret"&&e.jsx("span",{className:"block text-[11px] font-normal text-slate-500",children:"Shorter-lived"})]},s.value))}),u==="certificate"?e.jsxs("div",{className:"space-y-3",children:[e.jsxs("details",{className:"rounded-xl border border-slate-800 bg-slate-950/40 p-3",children:[e.jsx("summary",{className:"cursor-pointer text-xs font-medium text-cyan-400 hover:text-cyan-300",children:"Need to create a certificate? Show the commands"}),e.jsxs("div",{className:"mt-3 space-y-4",children:[e.jsxs("p",{className:"text-xs text-slate-400",children:["A self-signed certificate is fine — Entra does not require a CA. Generate one, upload the"," ",e.jsx("span",{className:"text-slate-300",children:"public"})," half to Entra (Certificates & secrets → Upload certificate), and paste both halves into the fields below."]}),e.jsxs("div",{children:[e.jsx("p",{className:"mb-1.5 text-xs font-semibold uppercase tracking-wider text-slate-500",children:"OpenSSL (any platform)"}),e.jsx(ne,{value:bt,label:"OpenSSL command"}),e.jsxs("ul",{className:"mt-2 list-disc space-y-1 pl-4 text-xs text-slate-500",children:[e.jsxs("li",{children:[e.jsx("span",{className:"font-mono text-slate-400",children:"-nodes"})," produces an unencrypted key. A passphrase-protected key cannot be used unattended and will fail at connect."]}),e.jsx("li",{children:"RSA 2048–4096 only."}),e.jsxs("li",{children:["Upload ",e.jsx("span",{className:"font-mono text-slate-400",children:"bluelantern-cert.pem"})," to Entra; paste it below as the certificate and ",e.jsx("span",{className:"font-mono text-slate-400",children:"bluelantern-key.pem"})," as the private key."]})]})]}),e.jsxs("div",{children:[e.jsx("p",{className:"mb-1.5 text-xs font-semibold uppercase tracking-wider text-slate-500",children:"PowerShell (Windows admins)"}),e.jsx(ne,{value:ft,label:"PowerShell command"}),e.jsxs("p",{className:"mt-2 text-xs text-slate-500",children:["Then extract the private key — the ",e.jsx("span",{className:"font-mono text-slate-400",children:".pfx"})," is not directly usable:"]}),e.jsx("div",{className:"mt-1.5",children:e.jsx(ne,{value:gt,label:"PFX extract command"})}),e.jsxs("p",{className:"mt-2 text-xs text-slate-500",children:[e.jsx("span",{className:"font-mono text-slate-400",children:"Export-Certificate"})," writes binary DER, not PEM — we accept PEM, raw DER, or base64 DER for the certificate, but the ",e.jsx("span",{className:"text-slate-300",children:"private key must be PEM"}),". Delete the ",e.jsx("span",{className:"font-mono text-slate-400",children:".pfx"})," and its password once extracted."]})]}),e.jsxs("p",{className:"text-xs text-slate-500",children:[e.jsx("span",{className:"text-slate-400",children:"Azure Key Vault"})," is the better enterprise option: create the certificate there and use its rotation to drive the renewal we warn about. The private key still has to reach us, so Key Vault helps with lifecycle rather than custody."]})]})]}),e.jsxs("div",{className:"rounded-lg border border-cyan-500/20 bg-cyan-500/5 px-3 py-2 text-xs text-slate-400",children:[e.jsx("span",{className:"font-semibold text-cyan-300",children:"On handing over a private key."})," Pasting one into a vendor form should give you pause, so to be explicit: it is transmitted once over TLS, stored only in AWS Secrets Manager (never our database), and never returned by any API. If you would rather not, the client-secret option is the alternative — at the cost of a shorter lifetime and an expiry we have to take on trust."]}),e.jsxs("div",{children:[e.jsxs("div",{className:"mb-1.5 flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs font-semibold uppercase tracking-wider text-slate-500",children:"Private key (PEM)"}),e.jsxs("label",{className:"inline-flex cursor-pointer items-center gap-1.5 rounded-lg border border-slate-700 bg-slate-950/60 px-2.5 py-1 text-xs font-medium text-slate-300 transition-colors hover:border-slate-600 hover:text-white",children:[e.jsx(be,{className:"h-3 w-3"}),"Upload",e.jsx("input",{type:"file",accept:".pem,.key,.txt",className:"hidden",onChange:s=>{const k=s.target.files?.[0];if(!k)return;const v=new FileReader;v.onload=()=>p(String(v.result||"")),v.readAsText(k),s.target.value=""}})]})]}),e.jsx("textarea",{value:j,onChange:s=>p(s.target.value),rows:3,placeholder:"-----BEGIN PRIVATE KEY-----",spellCheck:!1,className:"w-full rounded-xl border border-slate-700 bg-slate-950 px-4 py-2.5 font-mono text-xs text-white placeholder:text-slate-600 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-cyan-500"})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"mb-1.5 flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-xs font-semibold uppercase tracking-wider text-slate-500",children:"Certificate (PEM)"}),e.jsxs("label",{className:"inline-flex cursor-pointer items-center gap-1.5 rounded-lg border border-slate-700 bg-slate-950/60 px-2.5 py-1 text-xs font-medium text-slate-300 transition-colors hover:border-slate-600 hover:text-white",children:[e.jsx(be,{className:"h-3 w-3"}),"Upload",e.jsx("input",{type:"file",accept:".pem,.crt,.cer,.txt",className:"hidden",onChange:s=>{const k=s.target.files?.[0];if(!k)return;const v=new FileReader;v.onload=()=>d(String(v.result||"")),v.readAsText(k),s.target.value=""}})]})]}),e.jsx("textarea",{value:b,onChange:s=>d(s.target.value),rows:3,placeholder:"-----BEGIN CERTIFICATE-----",spellCheck:!1,className:"w-full rounded-xl border border-slate-700 bg-slate-950 px-4 py-2.5 font-mono text-xs text-white placeholder:text-slate-600 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-cyan-500"})]})]}):e.jsxs("div",{className:"space-y-3",children:[e.jsx("input",{type:"password",value:S,onChange:s=>w(s.target.value),placeholder:"Client secret value",spellCheck:!1,className:"w-full rounded-xl border border-slate-700 bg-slate-950 px-4 py-2.5 font-mono text-xs text-white placeholder:text-slate-600 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-cyan-500"}),e.jsxs("div",{children:[e.jsx("label",{className:"mb-1.5 block text-xs font-semibold uppercase tracking-wider text-slate-500",children:"Secret expires on (required)"}),e.jsx("input",{type:"date",value:m,onChange:s=>_(s.target.value),className:"w-full rounded-xl border border-slate-700 bg-slate-950 px-4 py-2.5 text-sm text-white focus:border-transparent focus:outline-none focus:ring-2 focus:ring-cyan-500 sm:w-64"}),e.jsx("p",{className:"mt-1.5 text-xs text-slate-500",children:"Copy the expiry shown on the Entra secret blade. A secret that lapses unnoticed silently stops monitoring, so we track it and warn you ahead of time."})]})]})]})]}),i===2&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-start gap-2 rounded-lg border border-amber-500/20 bg-amber-500/5 px-3 py-2 text-xs text-amber-400/90",children:[e.jsx(se,{className:"mt-0.5 h-3.5 w-3.5 shrink-0"}),e.jsxs("span",{children:[e.jsx("strong",{children:"Recommended"}),", run by an Exchange administrator. Without it the credential can read every mailbox in your organization. You can still connect — we will ask you to acknowledge it explicitly and record the decision — but narrowing the credential is the safer default."]})]}),e.jsxs("p",{className:"text-sm text-slate-400",children:["Fill these in and the script below updates with your values. Run it in"," ",e.jsx("span",{className:"text-slate-300",children:"Exchange Online PowerShell"}),". Skipping this is supported — continue to the next step and you will be offered the option to connect with tenant-wide access."]}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsxs("div",{children:[e.jsx("label",{className:"mb-2 block text-sm font-medium text-slate-300",children:"Exchange admin UPN"}),e.jsx("input",{type:"email",value:K,onChange:s=>M(s.target.value),placeholder:"[email protected]",className:"w-full rounded-xl border border-slate-700 bg-slate-950 px-4 py-2.5 font-mono text-xs text-white placeholder:text-slate-600 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-cyan-500"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"mb-2 block text-sm font-medium text-slate-300",children:"Your mail domain"}),e.jsx("input",{type:"text",value:F,onChange:s=>D(s.target.value),placeholder:"contoso.com",className:"w-full rounded-xl border border-slate-700 bg-slate-950 px-4 py-2.5 font-mono text-xs text-white placeholder:text-slate-600 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-cyan-500"})]})]}),e.jsxs("div",{children:[e.jsx("p",{className:"mb-2 text-sm font-medium text-slate-300",children:"PowerShell script"}),e.jsx(ne,{value:yt({adminUpn:K,clientId:h,domain:F}),label:"PowerShell script"}),e.jsxs("p",{className:"mt-2 text-xs text-slate-500",children:["Replace the example members with the mailboxes you want monitored, and run the two"," ",e.jsx("span",{className:"font-mono",children:"Test-ApplicationAccessPol
1icy"})," lines to confirm an in-scope mailbox is Granted and an out-of-scope one is Denied."]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"mb-2 block text-sm font-medium text-slate-300",children:"Monitored group"}),e.jsx("input",{type:"text",value:q,onChange:s=>f(s.target.value),placeholder:F.trim()?`BlueLantern-Monitored@${F.trim()}`:"[email protected]",spellCheck:!1,className:"w-full rounded-xl border border-slate-700 bg-slate-950 px-4 py-2.5 font-mono text-xs text-white placeholder:text-slate-600 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-cyan-500"}),e.jsxs("p",{className:"mt-2 text-sm text-slate-500",children:["Accepts an object id, mail address, alias, or display name. This is required either way — it defines"," ",e.jsx("span",{className:"text-slate-400",children:"who we analyze and seat"}),", whether or not you also enforce an access policy. A name matching two groups is refused rather than guessed; use the object id to disambiguate."]})]}),e.jsxs("p",{className:"flex items-start gap-1.5 text-xs text-slate-500",children:[e.jsx(C,{className:"mt-0.5 h-3.5 w-3.5 shrink-0"}),"Exchange policy changes can take up to about 30 minutes to propagate. If the next step reports unrestricted access immediately after running this, wait a few minutes and retry."]})]}),i===3&&e.jsxs(e.Fragment,{children:[I&&e.jsxs("div",{className:"rounded-xl border border-red-500/20 bg-red-500/10 p-4",children:[e.jsxs("div",{className:"flex items-start gap-3 text-red-400",children:[e.jsx(se,{className:"mt-0.5 h-5 w-5 shrink-0"}),e.jsxs("div",{className:"text-sm",children:[e.jsx("p",{className:"font-semibold",children:I.title}),W&&e.jsx("p",{className:"mt-1 text-red-300/90",children:W}),ee&&e.jsxs("p",{className:"mt-2 text-red-300/90",children:[I.evidenceLabel,":"," ",e.jsx("span",{className:"font-mono text-xs",children:ee})]}),re&&e.jsx("p",{className:"mt-2 text-xs text-amber-300/90",children:Ge})]})]}),e.jsx("div",{className:"mt-3 flex flex-wrap items-center gap-3",children:e.jsxs("button",{type:"button",onClick:()=>l(I.fixStep),className:"inline-flex shrink-0 items-center gap-1.5 whitespace-nowrap rounded-lg border border-red-400/30 bg-red-500/10 px-3 py-1.5 text-xs font-medium text-red-200 transition-colors hover:bg-red-500/20",children:[e.jsx(he,{className:"h-3.5 w-3.5"}),"Back to step ",I.fixStep+1]})})]}),I?.overridable&&e.jsx(ke,{onAccept:()=>z(!0),busy:N}),W&&!I&&e.jsxs("div",{className:"flex items-start gap-3 rounded-xl border border-red-500/20 bg-red-500/10 p-4 text-red-400",children:[e.jsx(C,{className:"mt-0.5 h-5 w-5 shrink-0"}),e.jsx("span",{className:"text-sm",children:W})]}),e.jsxs("p",{className:"text-sm text-slate-400",children:["Last step. We authenticate to Microsoft Graph, confirm your permissions were consented, and"," ",e.jsx("span",{className:"text-slate-300",children:"prove the access policy actually restricts us"})," — by checking that a mailbox inside your group is readable and one outside it is refused. Nothing is stored unless all of that passes."]}),e.jsxs("div",{className:"rounded-xl border border-slate-800 bg-slate-950/40 p-4 text-sm text-slate-400",children:[e.jsx("p",{className:"mb-2 font-semibold text-white",children:"Summary"}),e.jsxs("ul",{className:"space-y-1",children:[e.jsxs("li",{children:["Tenant: ",y.trim()?e.jsx("span",{className:"font-mono text-xs text-slate-300",children:y.trim()}):e.jsx("span",{className:"text-red-400",children:"missing"})]}),e.jsxs("li",{children:["Application: ",h.trim()?e.jsx("span",{className:"font-mono text-xs text-slate-300",children:h.trim()}):e.jsx("span",{className:"text-red-400",children:"missing"})]}),e.jsxs("li",{children:["Credential: ",u==="certificate"?"certificate":"client secret",u==="secret"&&m?` (expires ${m})`:""]}),e.jsxs("li",{children:["Monitored group: ",q.trim()?e.jsx("span",{className:"font-mono text-xs text-slate-300",children:q.trim()}):e.jsx("span",{className:"text-red-400",children:"missing"})]}),e.jsxs("li",{children:["Access: ",x?"read + auto-quarantine (Mail.ReadWrite)":"read-only"]})]})]})]}),e.jsxs("div",{className:"flex items-center justify-between gap-3 border-t border-slate-800 pt-4",children:[e.jsxs("button",{type:"button",onClick:()=>i===0?a():l(i-1),disabled:N,className:"inline-flex items-center gap-1.5 rounded-lg px-4 py-2 text-sm font-medium text-slate-400 transition-colors hover:bg-slate-800 hover:text-white disabled:opacity-50",children:[e.jsx(he,{className:"h-4 w-4"}),i===0?"Cancel":"Back"]}),i<me.length-1?e.jsxs("button",{type:"button",onClick:()=>l(i+1),className:"inline-flex items-center gap-1.5 rounded-lg bg-cyan-600 px-5 py-2 text-sm font-semibold text-white transition-colors hover:bg-cyan-500",children:["Next",e.jsx(oe,{className:"h-4 w-4"})]}):e.jsx("button",{type:"button",onClick:()=>z(!1),disabled:N,className:"inline-flex items-center gap-2 rounded-lg bg-cyan-600 px-5 py-2 text-sm font-semibold text-white transition-colors hover:bg-cyan-500 disabled:cursor-not-allowed disabled:opacity-50",children:N?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"h-4 w-4 animate-spin rounded-full border-2 border-white/30 border-t-white"}),"Verifying access…"]}):I||W?"Retry connection":"Connect Outlook"})]})]})})]})})}Ye.propTypes={onClose:c.func.isRequired,onConnected:c.func.isRequired};const Re={connected:"border-emerald-400/20 bg-emerald-400/10 text-emerald-400",pending:"border-amber-400/20 bg-amber-400/10 text-amber-400",disconnected:"border-slate-600/40 bg-slate-700/20 text-slate-400",error:"border-red-400/20 bg-red-400/10 text-red-400",reauth_required:"border-amber-400/20 bg-amber-400/10 text-amber-400"},Ot={reauth_required:"Reconnect needed"};function Je({status:a}){const t=String(a||"").toLowerCase();return e.jsx("span",{className:`inline-flex items-center whitespace-nowrap rounded-full border px-2.5 py-1 text-xs font-medium capitalize ${Re[t]||Re.disconnected}`,children:Ot[t]||t||"unknown"})}Je.propTypes={status:c.string};function Xe({integration:a}
1){if(String(a?.type).toLowerCase()!=="outlook")return null;const t=Be(a?.settings?.scope_verification);if(!t)return null;const o=t.tone==="ok";return e.jsxs("span",{className:`mt-1 inline-flex items-center gap-1 text-[11px] font-medium ${o?"text-emerald-400":"text-amber-400"}`,title:t.detail,children:[o?e.jsx(De,{className:"h-3 w-3"}):e.jsx(se,{className:"h-3 w-3"}),t.label,a?.settings?.unrestricted_acknowledged_by&&e.jsxs("span",{className:"font-normal text-slate-500",children:[" by ",a.settings.unrestricted_acknowledged_by]})]})}Xe.propTypes={integration:c.object};function fe({expiresAt:a}){const t=Tt(a);if(t===null)return null;const o=t<0,i=t<=30;return e.jsx("span",{className:`mt-0.5 block text-xs ${o?"text-red-400":i?"text-amber-400":"text-slate-500"}`,title:`Credential expires ${new Date(a).toLocaleDateString()}`,children:o?"Credential expired — monitoring stopped":i?`Credential expires in ${t} day${t===1?"":"s"}`:`Credential valid to ${new Date(a).toLocaleDateString()}`})}fe.propTypes={expiresAt:c.string};function Ze({onClose:a,onPick:t,locked:o,personalAccount:i}){return n.useEffect(()=>{const l=x=>{x.key==="Escape"&&a()};return window.addEventListener("keydown",l),()=>window.removeEventListener("keydown",l)},[a]),e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-slate-950/80 p-4 backdrop-blur-sm",onMouseDown:l=>{l.target===l.currentTarget&&a()},children:e.jsxs("div",{className:"flex max-h-[90vh] w-full max-w-lg flex-col overflow-hidden rounded-2xl border border-slate-800 bg-slate-900 shadow-2xl",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4 border-b border-slate-800 p-5 sm:p-6",children:[e.jsxs("div",{children:[e.jsxs("h3",{className:"flex items-center gap-2 text-lg font-semibold text-white",children:[e.jsx(pe,{className:"h-5 w-5 text-cyan-400"}),"Add Integration"]}),e.jsx("p",{className:"mt-1 text-sm text-slate-400",children:"Pick a service to connect to your account."})]}),e.jsx("button",{type:"button",onClick:a,"aria-label":"Close",className:"shrink-0 rounded-md p-1 text-slate-400 transition-colors hover:bg-slate-800 hover:text-white",children:e.jsx(ae,{className:"h-5 w-5"})})]}),e.jsx("div",{className:"space-y-3 overflow-y-auto p-5 sm:p-6",children:$e.map(l=>{const x=!!l.personal&&!i,g=l.available&&!o&&!x;return e.jsxs("button",{type:"button",disabled:!g,onClick:()=>
1g&&t(l.type),className:`flex w-full items-start gap-4 rounded-xl border p-4 text-left transition-colors ${g?"border-slate-700 bg-slate-950/60 hover:border-cyan-400/50":"cursor-not-allowed border-slate-800 bg-slate-950/30 opacity-60"}`,children:[e.jsx("div",{className:"rounded-lg bg-cyan-500/10 p-2.5 text-cyan-400",children:l.personal?e.jsx(Pe,{className:"h-5 w-5"}):l.type==="falcon"?e.jsx(je,{className:"h-5 w-5"}):l.type==="defender"?e.jsx(Ne,{className:"h-5 w-5"}):l.type==="outlook"?e.jsx(ye,{className:"h-5 w-5"}):e.jsx(ge,{className:"h-5 w-5"})}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"text-sm font-semibold text-white",children:l.label}),l.available?o?e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full border border-amber-500/30 bg-amber-500/10 px-2 py-0.5 text-[11px] font-medium text-amber-300",children:[e.jsx(Ve,{className:"h-3 w-3"}),"Requires seat plan"]}):x?e.jsx("span",{className:"rounded-full border border-slate-600/40 bg-slate-700/20 px-2 py-0.5 text-[11px] font-medium text-slate-400",children:"Personal accounts only"}):l.personal?e.jsx("span",{className:"rounded-full border border-cyan-500/30 bg-cyan-500/10 px-2 py-0.5 text-[11px] font-medium text-cyan-300",children:"Sign in with Microsoft"}):null:e.jsx("span",{className:"rounded-full border border-slate-600/40 bg-slate-700/20 px-2 py-0.5 text-[11px] font-medium text-slate-400",children:"Coming soon"})]}),e.jsx("p",{className:"mt-1 text-sm text-slate-400",children:l.description})]})]},l.type)})})]})})}Ze.propTypes={onClose:c.func.isRequired,onPick:c.func.isRequired,locked:c.bool,personalAccount:c.bool};function Qe({integration:a}){const t=a?.settings?.mfa_scan;if(!t?.enabled)return null;const o=String(t.status||"").toLowerCase(),i="mt-1 inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-[11px] font-medium";return o==="pending_permission"?e.jsxs("span",{className:`${i} border-amber-400/30 bg-amber-400/10 text-amber-300`,title:"The MFA scan needs the AuditLog.Read.All permission. Grant admin consent in Entra ID and re-run the connect flow. Mail monitoring is unaffected.",children:[e.jsx(ie,{className:"h-3 w-3"})," MFA scan: needs permission"]}):o==="error"?e.jsxs("span",{className:`${i} border-red-400/30 bg-red-400/10 text-red-300`,title:"The last MFA scan failed. Mail monitoring is unaffected.",children:[e.jsx(ie,{className:"h-3 w-3"})," MFA scan: error"]}):e.jsxs("span",{className:`${i} border-emerald-400/30 bg-emerald-400/10 text-emerald-300`,title:"Daily MFA posture scan is enabled.",children:[e.jsx(ie,{className:"h-3 w-3"})," MFA scan on"]})}Qe.propTypes={integration:c.object.isRequired};function et({integration:a}){const t=a?.settings||{},o=t.posture_checks||{};if(!o.forwarding&&!o.inbox_rules&&!o.mail_auth)return null;const i=String(t.mail_scan?.status||"").toLowerCase(),l="mt-1 inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-[11px] font-medium";return i==="pending_permission"?e.jsxs("span",{className:`${l} border-amber-400/30 bg-amber-400/10 text-amber-300`,title:"The forwarding and inbox-rule checks need the MailboxSettings.Read permission. Grant admin consent in Entra ID and re-run the connect flow. Mail monitoring is unaffected.",children:[e.jsx(de,{className:"h-3 w-3"})," Mail scan: needs permission"]}):i==="error"?e.jsxs("span",{className:`${l} border-red-400/30 bg-red-400/10 text-red-300`,title:"The last mail posture scan failed. Mail monitoring is unaffected.",children:[e.jsx(de,{className:"h-3 w-3"})," Mail scan: error"]}):e.jsxs("span",{className:`${l} border-emerald-400/30 bg-emerald-400/10 text-emerald-300`,title:"Daily mail posture scan is enabled.",children:[e.jsx(de,{className:"h-3 w-3"})," Mail scan on"]})}et.propTypes={integration:c.object.isRequired};function tt({integration:a,onClose:t,onSaved:o}){const{getValidToken:i}=Z(),l=a?.settings||{},x=l.spam_rules||{},g=String(a?.type).toLowerCase()==="outlook",[y,T]=n.useState(!!l.write_access),[h,A]=n.useState(l.pubsub_topic||""),[u,E]=n.useState(l.monitored_group||""),[j,p]=n.useState(!!x.enabled),b=l.mfa_scan||{},[d,S]=n.useState(!!b.enabled),w=l.posture_checks||{},m=l.mail_scan||{},[_,K]=n.useState(!!w.mail_auth),[M,F]=n.useState(!!w.forwarding),[D,q]=n.useState(!!w.inbox_rules),[f,N]=n.useState(!!w.dormant),[L,W]=n.useState(!!w.ai_exposure),O=!!m.directory_scan_acknowledged_at,[$,X]=n.useState(!1),G=(M||D)&&!O,[H,Q]=n.useState(Array.isArray(x.determinations)?x.determinations:["malicious"]),[Y,U]=n.useState(Number.isFinite(x.min_failed_checks)?String(x.min_failed_checks):""),[R,P]=n.useState(!1),[z,I]=n.useState(null);n.useEffect(()=>{const s=k=>{k.key==="Escape"&&!R&&t()};return window.addEventListener("keydown",s),()=>window.removeEventListener("keydown",s)},[t,R]);const ee=s=>{Q(k=>k.includes(s)?k.filter(v=>v!==s):[...k,s])},re=async()=>
1{if(!g&&h.trim()&&!qe(h)){I("The Pub/Sub topic must be the full name: projects/<your-project>/topics/<topic>.");return}if(g&&!u.trim()){I("The monitored group cannot be empty — it defines which mailboxes we may read.");return}if(G&&!$){I("To enable the forwarding or inbox-rule checks, confirm the directory-wide scan acknowledgement below.");return}P(!0),I(null);try{await Oe(i,{integrationId:a.id,settings:{write_access:y,mfa_scan:{enabled:d},posture_checks:{forwarding:M,inbox_rules:D,dormant:f,mail_auth:_,ai_exposure:L,...G&&$?{acknowledge_directory_scan:!0}:{}},...g?{monitored_group:u.trim()}:{pubsub_topic:h.trim()||null},spam_rules:{enabled:y&&j,determinations:H,min_failed_checks:Y===""?null:Number(Y),run_types:["EMAILANALYZER"]}}}),await o(),t()}catch(s){I(s.message||"Failed to save settings."),P(!1)}};return e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-slate-950/80 p-4 backdrop-blur-sm",onMouseDown:s=>{s.target===s.currentTarget&&!R&&t()},children:e.jsxs("div",{className:"flex max-h-[90vh] w-full max-w-lg flex-col overflow-hidden rounded-2xl border border-slate-800 bg-slate-900 shadow-2xl",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4 border-b border-slate-800 p-5 sm:p-6",children:[e.jsxs("div",{children:[e.jsxs("h3",{className:"flex items-center gap-2 text-lg font-semibold text-white",children:[e.jsx(ze,{className:"h-5 w-5 text-cyan-400"}),g?"Outlook Settings":"Gmail Settings"]}),e.jsx("p",{className:"mt-1 text-sm text-slate-400",children:l.monitored_group||l.domain||a?.id})]}),e.jsx("button",{type:"button",onClick:t,"aria-label":"Close",className:"shrink-0 rounded-md p-1 text-slate-400 transition-colors hover:bg-slate-800 hover:text-white",children:e.jsx(ae,{className:"h-5 w-5"})})]}),e.jsxs("div",{className:"space-y-5 overflow-y-auto p-5 sm:p-6",children:[z&&e.jsxs("div",{className:"flex items-start gap-3 rounded-xl border border-red-500/20 bg-red-500/10 p-4 text-red-400",children:[e.jsx(C,{className:"mt-0.5 h-5 w-5 shrink-0"}),e.jsx("span",{className:"text-sm",children:z})]}),e.jsxs("label",{className:"flex cursor-pointer items-start gap-3 rounded-xl border border-slate-700 bg-slate-950/60 p-4",children:[e.jsx("input",{type:"checkbox",checked:y,onChange:s=>{T(s.target.checked),s.target.checked||p(!1)},className:"mt-0.5 h-4 w-4 accent-cyan-500"}),e.jsxs("span",{className:"text-sm text-slate-300",children:[e.jsx("span",{className:"text-white",children:"Write access"})," (required for auto-quarantine)",e.jsx("span",{className:"block pt-1 text-xs text-slate-500",children:g?"Requires the Mail.ReadWrite application permission, consented in Entra ID. If it was not granted at connect time, grant it and re-run the connect flow — otherwise quarantine actions will fail.":"Requires the gmail.modify scope in your Workspace delegation grant. If it was not granted at connect time, grant it and re-run the connect flow — otherwise spam-move calls will fail."})]})]}),g&&e.jsxs("div",{className:"rounded-xl border border-slate-800 bg-slate-950/40 p-4",children:[e.jsx("p",{className:"mb-1 text-sm font-semibold text-white",children:"Monitored mailboxes"}),e.jsx(ve,{scopeCheck:l.scope_verification}),e.jsx("label",{className:"mb-2 mt-3 block text-xs font-semibold uppercase tracking-wider text-slate-500",children:"Monitored group"}),e.jsx("input",{type:"text",value:u,onChange:s=>E(s.target.value),placeholder:"[email protected]",spellCheck:!1,className:"w-full rounded-xl border border-slate-700 bg-slate-950 px-4 py-2.5 font-mono text-xs text-white placeholder:text-slate-600 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-cyan-500"}),e.jsxs("p",{className:"mt-2 flex items-start gap-1.5 text-xs text-amber-400/90",children:[e.jsx(C,{className:"mt-0.5 h-3.5 w-3.5 shrink-0"}),"Changing this re-seats users, but does not re-check your Exchange access policy. If you widen the group, update the policy in Exchange and re-run the connect flow so the scope is verified again."]})]}),!g&&e.jsxs("div",{className:"rounded-xl border border-slate-800 bg-slate-950/40 p-4",children:[e.jsx("p",{className:"mb-1 text-sm font-semibold text-white",children:"Real-time mail delivery (Pub/Sub)"}),l.pubsub_topic?e.jsx("p",{className:"mb-3 text-xs text-emerald-400",children:"Configured — new mail is delivered for analysis automatically."}):e.jsx("p",{className:"mb-3 text-xs text-amber-400/90",children:"Not configured yet — until this is set up, mailboxes are not monitored in real time."}),e.jsxs("details",{className:"group mb-3",children:[e.jsx("summary",{className:"cursor-pointer text-xs font-medium text-cyan-400 hover:text-cyan-300",children:l.pubsub_topic?"Show setup steps":"Show setup steps (do this in your Google Cloud console)"}),e.jsx("div",{className:"mt-3",children:e.jsx(we,{endpoint:l.push_token?Le(`/integrations/gmail/notifications/${l.push_token}
1`):null,oidcServiceAccount:l.client_email||null,audience:"bluelantern-gmail-push"})})]}),e.jsx("label",{className:"mb-2 block text-xs font-semibold uppercase tracking-wider text-slate-500",children:"Pub/Sub topic (full name)"}),e.jsx("input",{type:"text",value:h,onChange:s=>A(s.target.value),placeholder:"projects/your-project/topics/bluelantern-gmail",spellCheck:!1,className:"w-full rounded-xl border border-slate-700 bg-slate-950 px-4 py-2.5 font-mono text-xs text-white placeholder:text-slate-600 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-cyan-500"}),e.jsx("p",{className:"mt-2 text-xs text-slate-500",children:"Watches arm automatically on the next daily sweep after saving."})]}),e.jsxs("div",{className:"rounded-xl border border-slate-800 bg-slate-950/40 p-4",children:[e.jsxs("label",{className:"flex cursor-pointer items-center gap-3",children:[e.jsx("input",{type:"checkbox",checked:j,onChange:s=>p(s.target.checked),disabled:!y,className:"h-4 w-4 accent-cyan-500"}),e.jsx("span",{className:`text-sm font-semibold ${y?"text-white":"text-slate-500"}`,children:g?"Move matching mail to Junk Email automatically":"Move matching mail to Spam automatically"})]}),!y&&e.jsx("p",{className:"mt-2 text-xs text-slate-500",children:"Enable write access above to use this."}),String(a?.status).toLowerCase()!=="connected"&&e.jsxs("p",{className:"mt-2 flex items-start gap-1.5 text-xs text-amber-400/90",children:[e.jsx(C,{className:"mt-0.5 h-3.5 w-3.5 shrink-0"}),"These rules only run once the integration is connected — it is currently"," ",String(a?.status||"not connected").toLowerCase(),"."]}),j&&y&&e.jsxs("div",{className:"mt-4 space-y-4",children:[e.jsxs("div",{children:[e.jsx("p",{className:"mb-2 text-xs font-semibold uppercase tracking-wider text-slate-500",children:"When the verdict is"}),e.jsx("div",{className:"flex flex-wrap gap-2",children:Lt.filter(s=>!s.label.includes("(device)")).map(s=>e.jsx("button",{type:"button",onClick:()=>ee(s.value),className:`rounded-full border px-3 py-1.5 text-xs font-medium transition-colors ${H.includes(s.value)?"border-cyan-400/60 bg-cyan-400/10 text-cyan-300":"border-slate-700 bg-slate-950/60 text-slate-400 hover:border-slate-600"}`,children:s.label},s.value))})]}),e.jsxs("div",{className:"flex items-center gap-2 text-sm text-slate-300",children:[e.jsx("span",{children:"or at least"}),e.jsx("input",{type:"number",min:"0",value:Y,onChange:s=>U(s.target.value),placeholder:"any",className:"w-20 rounded-lg border border-slate-700 bg-slate-950 px-3 py-1.5 text-center text-sm text-white placeholder:text-slate-600 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-cyan-500"}),e.jsx("span",{children:"failed checks"})]})]})]}),e.jsxs("div",{className:"rounded-xl border border-slate-800 bg-slate-950/40 p-4",children:[e.jsxs("label",{className:"flex cursor-pointer items-center gap-3",children:[e.jsx("input",{type:"checkbox",checked:d,onChange:s=>S(s.target.checked),className:"h-4 w-4 accent-cyan-500"}),e.jsx("span",{className:"text-sm font-semibold text-white",children:"Daily MFA posture scan"})]}),e.jsxs("p",{className:"mt-2 text-xs text-slate-500",children:["Once a day, checks every user in your directory for a registered MFA method. Admins without MFA are flagged critical, other users high. Results appear in the"," ",e.jsx(J,{to:"/monitoring-hub",className:"text-cyan-400 hover:text-cyan-300 hover:underline",children:"Monitoring Hub"})," ","under the Identity type. The scan reads the whole directory, including users whose mailboxes are not monitored."]}),e.jsxs("label",{className:"mt-3 flex cursor-pointer items-center gap-3",children:[e.jsx("input",{type:"checkbox",checked:f,onChange:s=>N(s.target.checked),className:"h-4 w-4 accent-cyan-500"}),e.jsx("span",{className:"text-sm font-semibold text-white",children:"Dormant account check"})]}),e.jsx("p",{className:"mt-2 text-xs text-slate-500",children:"Flags enabled accounts with no sign-in for 90 days (30 days for admins) as part of the same identity posture report. Dormant admins are critical findings."}),(d||f)&&(g?e.jsxs("p",{className:"mt-2 flex items-start gap-1.5 text-xs text-amber-400/90",children:[e.jsx(C,{className:"mt-0.5 h-3.5 w-3.5 shrink-0"}),"MFA and dormancy both require the AuditLog.Read.All application permission with admin consent in Entra ID, and the dormancy check additionally requires an Entra ID P1 or P2 license on the tenant. If the permission was not granted at connect time, grant it and re-run the connect flow. Until it verifies, the scan shows needs permission and mail monitoring continues unaffected."]}):e.jsx("p",{className:"mt-2 text-xs text-slate-500",children:"No new permissions needed. The directory scope in your existing delegation grant already covers both checks."})),String(b.status||"").toLowerCase()==="pending_permission"&&e.jsxs("p",{className:"mt-2 flex items-start gap-1.5 text-xs text-amber-400/90",children:[e.jsx(C,{className:"mt-0.5 h-3.5 w-3.5 shrink-0"}),"Waiting on permission: grant AuditLog.Read.All in Entra ID and re-run the connect flow to activate the scan."]}),b.last_summary&&e.jsxs("p",{className:"mt-2 text-xs text-slate-400",children:["Last scan: ",Number(b.last_summary.mfa_registered??0).toLocaleStr
1ing()," of"," ",Number(b.last_summary.users_scanned??0).toLocaleString()," users have MFA registered",Number(b.last_summary.admins_without_mfa??0)>0&&e.jsxs("span",{className:"text-red-400",children:[" ","· ",Number(b.last_summary.admins_without_mfa).toLocaleString()," admin",Number(b.last_summary.admins_without_mfa)===1?"":"s"," without MFA"]}),b.last_summary.enforcement_evaluated===!0&&e.jsxs("span",{className:b.last_summary.enforcement_severity==="high"?"text-red-400":b.last_summary.enforcement_severity?"text-amber-400":"",children:[" ","· MFA enforced for ",Number(b.last_summary.mfa_enforced??0).toLocaleString(),"/",Number(b.last_summary.users_scanned??0).toLocaleString()]}),"."]})]}),e.jsxs("div",{className:"rounded-xl border border-slate-800 bg-slate-950/40 p-4",children:[e.jsx("p",{className:"text-sm font-semibold text-white",children:"Daily mail posture scan"}),e.jsxs("p",{className:"mt-1 text-xs text-slate-500",children:["Once a day, checks the ways mail can leak from your org. Results appear in the"," ",e.jsx(J,{to:"/monitoring-hub",className:"text-cyan-400 hover:text-cyan-300 hover:underline",children:"Monitoring Hub"})," ","under the Mail Posture type."]}),e.jsxs("div",{className:"mt-3 space-y-2",children:[e.jsxs("label",{className:"flex cursor-pointer items-start gap-3",children:[e.jsx("input",{type:"checkbox",checked:M,onChange:s=>F(s.target.checked),className:"mt-0.5 h-4 w-4 accent-cyan-500"}),e.jsxs("span",{className:"text-sm text-slate-300",children:[e.jsx("span",{className:"font-semibold text-white",children:"Auto-forwarding"}),e.jsx("span",{className:"block pt-0.5 text-xs text-slate-500",children:"External auto-forwards and forwarding rules, the classic BEC persistence move. Admin forwards are critical findings."})]})]}),e.jsxs("label",{className:"flex cursor-pointer items-start gap-3",children:[e.jsx("input",{type:"checkbox",checked:D,onChange:s=>q(s.target.checked),className:"mt-0.5 h-4 w-4 accent-cyan-500"}),e.jsxs("span",{className:"text-sm text-slate-300",children:[e.jsx("span",{className:"font-semibold text-white",children:"Suspicious inbox rules"}),e.jsx("span",{className:"block pt-0.5 text-xs text-slate-500",children:"Rules that delete, hide, or divert mail in patterns associated with account compromise."})]})]}),e.jsxs("label",{className:"flex cursor-pointer items-start gap-3",children:[e.jsx("input",{type:"checkbox",checked:_,onChange:s=>K(s.target.checked),className:"mt-0.5 h-4 w-4 accent-cyan-500"}),e.jsxs("span",{className:"text-sm text-slate-300",children:[e.jsx("span",{className:"font-semibold text-white",children:"Mail authentication (DMARC, SPF, DKIM)"}),e.jsx("span",{className:"block pt-0.5 text-xs text-slate-500",children:"DNS posture of your sending domains. A domain without DMARC lets anyone send mail as your org."})]})]})]}),G&&e.jsxs("label",{className:"mt-3 flex cursor-pointer items-start gap-3 rounded-lg border border-amber-500/20 bg-amber-500/5 p-3",children:[e.jsx("input",{type:"checkbox",checked:$,onChange:s=>X(s.target.checked),className:"mt-0.5 h-4 w-4 accent-amber-500"}),e.jsxs("span",{className:"text-xs text-amber-100/90",children:["I understand the forwarding and inbox-rule checks read and store mailbox forwarding and inbox-rule contents for ",e.jsx("span",{className:"font-semibold",children:"every user in the directory"}),", not only monitored-group members. This acknowledgement is recorded once with my name and the time."]})]}),O&&(M||D)&&e.jsxs("p",{className:"mt-2 text-xs text-slate-500",children:["Directory-wide scan acknowledged ",new Date(m.directory_scan_acknowledged_at).toLocaleDateString(),m.directory_scan_acknowledged_by?` by ${m.directory_scan_acknowledged_by}`:"","."]}),(M||D)&&(g?e.jsxs("p",{className:"mt-3 flex items-start gap-1.5 text-xs text-amber-400/90",children:[e.jsx(C,{className:"mt-0.5 h-3.5 w-3.5 shrink-0"}),"Forwarding and inbox-rule checks require the MailboxSettings.Read application permission with admin consent in Entra ID. If it was not granted at connect time, grant it and re-run the connect flow. Until it verifies, these checks show needs permission and mail monitoring continues unaffected. An Exchange Application Access Policy scopes these reads the same way it scopes mail."]}):e.jsx("p",{className:"mt-3 text-xs text-slate-500",children:"No new permissions needed. The gmail.readonly scope in your existing delegation grant already covers forwarding and rule reads."})),_&&!M&&!D&&e.jsx("p",{className:"mt-3 text-xs text-slate-500",children:"Mail authentication uses public DNS lookups only; no permissions on either provider."}),String(m.status||"").toLowerCase()==="pending_permission"&&e.jsxs("p",{className:"mt-2 flex items-start gap-1.5 text-xs text-amber-400/90",children:[e.jsx(C,{className:"mt-0.5 h-3.5 w-3.5 shrink-0"}),"Waiting on permission: grant MailboxSettings.Read in Entra ID and re-run the connect flow to activate the forwarding and inbox-rule checks."]}),m.last_summary&&e.jsxs("p",{className:"mt-2 text-xs text-slate-400",children:["Last scan: ",Number(m.last_summary.users_scanned??0)>0&&e.jsxs(e.Fragment,{children:[Number(m.last_summary.users_scanned).toLocaleStr
1ing()," users and "]}),Number(m.last_summary.domains_checked??0).toLocaleString()," domain",Number(m.last_summary.domains_checked??0)===1?"":"s"," checked",Number(m.last_summary.findings_critical??0)>0&&e.jsxs("span",{className:"text-red-400",children:[" ","· ",Number(m.last_summary.findings_critical).toLocaleString()," critical"]}),Number(m.last_summary.findings_high??0)>0&&e.jsxs("span",{className:"text-orange-400",children:[" ","· ",Number(m.last_summary.findings_high).toLocaleString()," high"]}),"."]})]}),e.jsxs("div",{className:"rounded-xl border border-slate-800 bg-slate-950/40 p-4",children:[e.jsxs("label",{className:"flex cursor-pointer items-center gap-3",children:[e.jsx("input",{type:"checkbox",checked:L,onChange:s=>W(s.target.checked),className:"h-4 w-4 accent-cyan-500"}),e.jsx("span",{className:"text-sm font-semibold text-white",children:"Daily AI exposure scan"})]}),e.jsxs("p",{className:"mt-2 text-xs text-slate-500",children:["Once a day, inventories the third-party OAuth apps granted access to your org's data: AI tools that can reach mail, files, or calendars, plus unverified apps holding data scopes (the classic OAuth-phishing shape). Reads grant metadata only — app identities and scope strings, never message or file content. Results appear in the"," ",e.jsx(J,{to:"/monitoring-hub",className:"text-cyan-400 hover:text-cyan-300 hover:underline",children:"Monitoring Hub"})," ","under the AI Exposure type, and apps newly appearing after the first scan can trigger alert rules on that type."]}),L&&(g?e.jsxs("p",{className:"mt-2 flex items-start gap-1.5 text-xs text-amber-400/90",children:[e.jsx(C,{className:"mt-0.5 h-3.5 w-3.5 shrink-0"}),"Requires the Application.Read.All application permission with admin consent in Entra ID. If it was not granted at connect time, grant it and re-run the connect flow. Mail monitoring continues unaffected either way."]}):e.jsxs("p",{className:"mt-2 flex items-start gap-1.5 text-xs text-amber-400/90",children:[e.jsx(C,{className:"mt-0.5 h-3.5 w-3.5 shrink-0"}),"Requires the admin.directory.user.security scope added to your existing domain-wide delegation grant (Security → API controls → Domain-wide delegation — same client ID, add the scope). The next daily scan picks it up; mail monitoring continues unaffected either way."]}))]})]}),e.jsxs("div",{className:"flex justify-end gap-3 border-t border-slate-800 p-5 sm:p-6",children:[e.jsx("button",{type:"button",onClick:t,disabled:R,className:"rounded-lg px-4 py-2 text-sm font-medium text-slate-400 transition-colors hover:bg-slate-800 hover:text-white disabled:opacity-50",children:"Cancel"}),e.jsx("button",{type:"button",onClick:re,disabled:R,className:"inline-flex items-center gap-2 rounded-lg bg-cyan-600 px-5 py-2 text-sm font-semibold text-white transition-colors hover:bg-cyan-500 disabled:cursor-not-allowed disabled:opacity-50",children:R?"Saving…":"Save Settings"})]})]})})}tt.propTypes={integration:c.object.isRequired,onClose:c.func.isRequired,onSaved:c.func.isRequired};function st({integration:a,onCancel:t,onConfirm:o,loading:i,error:l}){const x=We(a?.type);return e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-slate-950/80 p-4 backdrop-blur-sm",onMouseDown:g=>{g.target===g.currentTarget&&!i&&t()},children:e.jsxs("div",{className:"w-full max-w-md rounded-2xl border border-slate-800 bg-slate-900 p-6 shadow-2xl",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"rounded-lg bg-red-500/10 p-2 text-red-400",children:e.jsx(Ue,{className:"h-5 w-5"})}),e.jsx("h3",{className:"text-lg font-semibold text-white",children:"Remove Integration"})]}),e.jsxs("p",{className:"mt-4 text-sm text-slate-300",children:["Remove ",e.jsx("span",{className:"font-medium text-white",children:x?.label||a?.type}),a?.settings?.domain?e.jsxs(e.Fragment,{children:[" for ",e.jsx("span",{className:"font-mono text-cyan-300",children:a.settings.domain})]}):null,"? Syncing and ingestion stop, and the stored credentials are discarded."]}),a?.type==="outlook_personal"?e.jsxs("p",{className:"mt-2 text-xs text-slate-500",children:["This stops inbox monitoring, deletes our copy of your Microsoft sign-in token, and erase
1s the mailbox record. Microsoft does not let apps revoke their own grant, so to remove Blue Lantern on their side as well, open"," ",e.jsx("a",{href:Mt,target:"_blank",rel:"noopener noreferrer",className:"text-cyan-400 hover:text-cyan-300 hover:underline",children:"account.live.com/consent"})," ","and remove the app."]}):a?.type==="falcon"?e.jsx("p",{className:"mt-2 text-xs text-slate-500",children:"Daily device-health scans stop and our copy of the API credential is erased. The API client itself stays in your Falcon console until you delete it there (Support and resources → API clients & keys)."}):a?.type==="defender"?e.jsx("p",{className:"mt-2 text-xs text-slate-500",children:"Daily device-health scans stop and our copy of the client secret is erased. The app registration itself stays in your Entra tenant until you delete it there (Entra admin center → App registrations)."}):e.jsx("p",{className:"mt-2 text-xs text-slate-500",children:"The delegation grant itself stays in your Google Workspace admin console until you revoke it there (Security → API controls → Domain-wide delegation)."}),l&&e.jsxs("p",{className:"mt-3 flex items-center gap-1.5 text-sm text-red-400",children:[e.jsx(C,{className:"h-4 w-4"}),l]}),e.jsxs("div",{className:"mt-6 flex justify-end gap-3",children:[e.jsx("button",{type:"button",onClick:t,disabled:i,className:"rounded-lg px-4 py-2 text-sm font-medium text-slate-400 transition-colors hover:bg-slate-800 hover:text-white disabled:opacity-50",children:"Cancel"}),e.jsx("button",{type:"button",onClick:o,disabled:i,className:"inline-flex items-center gap-2 rounded-lg bg-red-600 px-4 py-2 text-sm font-semibold text-white transition-colors hover:bg-red-500 disabled:cursor-not-allowed disabled:opacity-50",children:i?"Removing…":"Remove"})]})]})})}st.propTypes={integration:c.object,onCancel:c.func.isRequired,onConfirm:c.func.isRequired,loading:c.bool,error:c.string};function at({integration:a,onClose:t,onRefresh:o}){n.useEffect(()=>{const l=x=>{x.key==="Escape"&&t()};return window.addEventListener("keydown",l),()=>window.removeEventListener("keydown",l)},[t]);const i=a?.settings||{};return e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-slate-950/80 p-4 backdrop-blur-sm",onMouseDown:l=>{l.target===l.currentTarget&&t()},children:e.jsxs("div",{className:"flex max-h-[90vh] w-full max-w-xl flex-col overflow-hidden rounded-2xl border border-slate-800 bg-slate-900 shadow-2xl",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4 border-b border-slate-800 p-5 sm:p-6",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("h3",{className:"flex items-center gap-2 text-lg font-semibold text-white",children:[e.jsx(se,{className:"h-5 w-5 shrink-0 text-amber-400"}),"Verify access scope"]}),e.jsx("p",{className:"mt-1 truncate text-sm text-slate-400",title:i.monitored_group||a?.id,children:i.monitored_group||a?.id})]}),e.jsx("button",{type:"button",onClick:t,"aria-label":"Close",className:"shrink-0 rounded-md p-1 text-slate-400 transition-colors hover:bg-slate-800 hover:text-white",children:e.jsx(ae,{className:"h-5 w-5"})})]}),e.jsx("div",{className:"overflow-y-auto p-5 sm:p-6",children:e.jsx(Se,{pending:{reason:i.scope_verification?.reason||i.pending_reason,message:i.scope_verification?.message||a?.last_error,scope_check:i.scope_verification,retry_after_seconds:a?.retry_after_seconds??0},onVerified:()=>{o(),t()},onRefresh:o})})]})})}at.propTypes={integration:c.object.isRequired,onClose:c.func.isRequired,onRefresh:c.func.isRequired};function nt({existing:a,onClose:t,onConnected:o}){const{getValidToken:i}=Z(),l=a?.settings||{},[x,g]=n.useState(l.client_id||""),[y,T]=n.useState(""),[h,A]=n.useState(_e.includes(l.region)?l.region:"us-1"),[u,E]=n.useState(!1),[j,p]=n.useState("");n.useEffect(()=>{const d=S=>{S.key==="Escape"&&!u&&t()};return window.addEventListener("keydown",d),()=>window.removeEventListener("keydown",d)},[t,u]);const b=async()=>{const d=x.trim(),S=y.trim();if(!d||!S){p("Enter both the client ID and the client secret from your Falcon API client.");return}E(!0),p("");try{await Dt(i,{clientId:d,clientSecret:S,region:h}),o()}catch(w){w.status===402?p("Falcon monitoring requires an active Seat License. Add seats on the Organization page, then connect again."):w.status===403?p("Integrations are managed by account admins. Ask an admin of this account to connect Falcon."):w.status===502?p(`${w.message||"CrowdStrike could not be reached."} Try again in a moment.`):p(w.message||"The connection could not be completed.")}finally{E(!1)}};return e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-slate-950/80 p-4 backdrop-blur-sm",onMouseDown:d=>{d.target===d.currentTarget&&!u&&t()},children:e.jsxs("div",{className:"flex max-h-[90vh] w-full max-w-xl flex-col overflow-hidden rounded-2xl border border-slate-800 bg-slate-900 shadow-2xl",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4 border-b border-slate-800 p-5 sm:p-6",children:[e.jsxs("div",{children:[e.jsxs("h3",{className:"flex items-center gap-2 text-lg font-semibold text-white",children:[e.jsx(je,{className:"h-5 w-5 shrink-0 text-cyan-400"}),a?"Reconnect CrowdStrike Falcon":"Connect CrowdStrike Falcon"]}),e.jsx("p",{className:"mt-1 text-sm text-slate-400",children:"Read-only agent-health and alert-presence monitoring for your Falcon-protected devices. Each device gets a daily health run in the Monitoring Hub."})]}),e.jsx("button",{type:"button",onClick:t,"aria-label":"Close",className:"shrink-0 rounded-md p-1 text-slate-400 transition-colors hover:bg-slate-800 hover:text-white",children:e.jsx(ae,{className:"h-5 w-5"})})]}),e.jsxs("div",{className:"space-y-5 overflow-y-auto p-5 sm:p-6",children:[e.jsxs("div",{className:"rounded-xl border border-slate-800 bg-slate-950/60 p-4 text-sm text-slate-300",children:[e.jsx("p",{className:"font-semibold text-white",children:"Create the API client in your Falcon console"}),e.jsxs("p",{className:"mt-1.5 text-slate-400",children:["Falcon console → ",e.jsx("span",{className:"text-slate-300",children:"Support and resources → API clients & keys → Create client"}),", with exactly three scopes: ",e.jsx("span",{className:"font-semibold text-white",children:"Hosts: Read"}),","," ",e.jsx("span",{className:"font-semibold text-white",children:"User Management: Read"}),", and"," ",e.jsx("span",{className:"font-semibold text-white",children:"Alerts: Read"})," (all read-only — no host content or vulnerability data, and alert reads are presence-only counts per device, never alert contents). Your cloud region is displayed next to the created client. Without Alerts: Read the open-alert check is simply omitted; the health checks still run."]})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"falcon-client-id",className:"block text-sm font-medium text-slate-300",children:"Client ID"}),e.jsx("input",{id:"falcon-client-id",type:"text",value:x,onChange:d=>{g(d.target.value),p("")},autoComplete:"off",spellCheck:"false",className:"mt-1.5 w-full rounded-lg border border-slate-700 bg-slate-950/60 px-3 py-2 font-mono text-sm text-white placeholder-slate-600 focus:border-cyan-400/50 focus:outline-none focus:ring-2 focus:ring-cyan-400/20"})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"falcon-client-secret",className:"block text-sm font-medium text-slate-300",children:"Client secret"}),e.jsx("input",{id:"falcon-client-secret",type:"password",value:y,onChange:d=>{T(d.target.value),p("")},autoComplete:"off",className:"mt-1.5 w-full rounded-lg border border-slate-700 bg-slate-950/60 px-3 py-2 font-mono text-sm text-white placeholder-slate-600 focus:border-cyan-400/50 focus:outline-none focus:ring-2 focus:ring-cyan-400/20"}),e.jsx("p",{className:"mt-1 text-xs text-slate-500",children:"Shown once by CrowdStrike when the client is created, and never displayed here after connecting. To rotate the credential later, re-enter both values on this form."})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"falcon-region",className:"block text-sm font-medium text-slate-300",children:"Cloud region"}),e.jsx("select",{id:"falcon-region",value:h,onChange:d=>{A(d.target.value),p("")},className:"mt-1.5 w-full rounded-lg border border-slate-700 bg-slate-950/60 px-3 py-2 text-sm text-white focus:border-cyan-400/50 focus:outline-none focus:ring-2 focus:ring-cyan-400/20",children:_e.map(d=>e.jsx("option",{value:d,children:d},d))}),e.jsx("p",{className:"mt-1 text-xs text-slate-500",children:"Displayed next to the API client in the Falcon console. A wrong region reads as a rejected credential."})]}),j&&e.jsxs("p",{className:"flex items-start gap-1.5 text-sm text-red-400",children:[e.jsx(C,{className:"mt-0.5 h-4 w-4 shrink-0"}),j]})]}),e.jsxs("div",{className:"flex justify-end gap-3 border-t border-slate-800 p-5 sm:p-6",children:[e.jsx("button",{type:"button",onClick:t,disabled:u,className:"rounded-lg px-4 py-2 text-sm font-medium text-slate-400 transition-colors hover:bg-slate-800 hover:text-white disabled:opacity-50",children:"Cancel"}),e.jsx("button",{type:"button",onClick:b,disabled:u,className:"inline-flex items-center gap-2 rounded-lg bg-cyan-600 px-5 py-2 text-sm font-semibold text-white transition-colors hover:bg-cyan-500 disabled:cursor-not-allowed disabled:opacity-50",children:u?"Validating credential…":a?"Reconnect":"Connect"})]})]})})}nt.propTypes={existing:c.object,onClose:c.func.isRequired,onConnected:c.func.isRequired};function rt({existing:a,onClose:t,onConnected:o}){const{getValidToken:i}=Z(),l=a?.settings||{},[x,g]=n.useState(l.tenant_id||""),[y,T]=n.useState(l.client_id||""),[h,A]=n.useState(""),[u,E]=n.useState(!1),[j,p]=n.useState("");n.useEffect(()=>{const d=S=>{S.key==="Escape"&&!u&&t()};return window.addEventListener("keydown",d),()=>window.removeEventListener("keydown",d)},[t,u]);const b=async()=>{const d=x.trim(),S=y.trim(),w=h.trim();if(!d||!S||!w){p("Enter the tenant ID, application (client) ID, and client secret from your Entra app registration.");return}E(!0),p("");try{await Pt(i,{tenantId:d,clientId:S,clientSecret:w}),o()}catch(m){m.status===402?p("Defender monitoring requires an active Seat License. Add seats on the Organization page, then connect again."):m.status===403?p("Integrations are managed by account admins. Ask an admin of this account to connect Defender."):m.status===502?p(`${m.message||"Microsoft could not be reached."} Try again in a moment.`):p(m.message||"The connection could not be completed.")}finally{E(!1)}};return e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-slate-950/80 p-4 backdrop-blur-sm",onMouseDown:d=>{d.target===d.currentTarget&&!u&&t()},children:e.jsxs("div",{className:"flex max-h-[90vh] w-full max-w-xl flex-col overflow-hidden rounded-2xl border border-slate-800 bg-slate-900 shadow-2xl",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4 border-b border-slate-800 p-5 sm:p-6",children:[e.jsxs("div",{children:[e.jsxs("h3",{className:"flex items-center gap-2 text-lg font-semibold text-white",children:[e.jsx(Ne,{className:"h-5 w-5 shrink-0 text-cyan-400"}),a?"Reconnect Microsoft Defender":"Connect Microsoft Defender"]}),e.jsx("p",{className:"mt-1 text-sm text-slate-400",children:"Read-only agent-health and alert-presence monitoring for your Defender-onboarded devices. Each device gets a daily health run in the Monitoring Hub."})]}),e.jsx("button",{type:"button",onClick:t,"aria-label":"Close",className:"shrink-0 rounded-md p-1 text-slate-400 transition-colors hover:bg-slate-800 hover:text-white",children:e.jsx(ae,{className:"h-5 w-5"})})]}),e.jsxs("div",{className:"space-y-5 overflow-y-auto p-5 sm:p-6",children:[e.jsxs("div",{className:"rounded-xl border border-slate-800 bg-slate-950/60 p-4 text-sm text-slate-300",children:[e.jsx("p",{className:"font-semibold text-white",children:"Register the app in your Entra admin center"}),e.jsxs("p",{className:"mt-1.5 text-slate-400",children:["Entra admin center → ",e.jsx("span",{className:"text-slate-300",children:"App registrations → New registration"})," (any name, single tenant). Then ",e.jsx("span",{className:"text-slate-300",children:"API permissions → Add → APIs my organization uses"})," → search ",e.jsx("span",{className:"font-mono text-xs text-cyan-300/90",children:"WindowsDefenderATP"})," →"," ",e.jsx("span",{className:"text-slate-300",children:"Application permissions"})," → add"," ",e.jsx("span",{className:"font-semibold text-white",children:"Machine.Read.All"}),","," ",e.jsx("span",{className:"font-semibold text-white",children:"Alert.Read.All"}),", and"," ",e.jsx("span",{className:"font-semibold text-white",children:"User.Read.All"})," → Grant admin consent. Then"," ",e.jsx("span",{className:"text-slate-300",children:"Certificates & secrets → New client secret"}),". Your tenant ID and application (client) ID are on the app's Overview page."]}),e.jsx("p",{className:"mt-2 text-xs text-slate-500",children:"All three permissions are read-only. Alert reads are presence-only counts per device, never alert contents; without Alert.Read.All the open-alert check is simply omitted, and User.Read.All only improves device-
1owner attribution."})]}),e.jsx("p",{className:"text-xs text-slate-500",children:"Requires Microsoft Defender for Endpoint P2 or Microsoft Defender for Business. Defender for Business supports this integration with some Microsoft-documented API limitations (reduced alert detail and API rate caps); device health and alert-presence checks work on both."}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"defender-tenant-id",className:"block text-sm font-medium text-slate-300",children:"Tenant ID"}),e.jsx("input",{id:"defender-tenant-id",type:"text",value:x,onChange:d=>{g(d.target.value),p("")},autoComplete:"off",spellCheck:"false",className:"mt-1.5 w-full rounded-lg border border-slate-700 bg-slate-950/60 px-3 py-2 font-mono text-sm text-white placeholder-slate-600 focus:border-cyan-400/50 focus:outline-none focus:ring-2 focus:ring-cyan-400/20"})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"defender-client-id",className:"block text-sm font-medium text-slate-300",children:"Application (client) ID"}),e.jsx("input",{id:"defender-client-id",type:"text",value:y,onChange:d=>{T(d.target.value),p("")},autoComplete:"off",spellCheck:"false",className:"mt-1.5 w-full rounded-lg border border-slate-700 bg-slate-950/60 px-3 py-2 font-mono text-sm text-white placeholder-slate-600 focus:border-cyan-400/50 focus:outline-none focus:ring-2 focus:ring-cyan-400/20"})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"defender-client-secret",className:"block text-sm font-medium text-slate-300",children:"Client secret"}),e.jsx("input",{id:"defender-client-secret",type:"password",value:h,onChange:d=>{A(d.target.value),p("")},autoComplete:"off",className:"mt-1.5 w-full rounded-lg border border-slate-700 bg-slate-950/60 px-3 py-2 font-mono text-sm text-white placeholder-slate-600 focus:border-cyan-400/50 focus:outline-none focus:ring-2 focus:ring-cyan-400/20"}),e.jsx("p",{className:"mt-1 text-xs text-slate-500",children:"Shown once by Entra when the secret is created, and never displayed here after connecting. Entra secrets expire (24 months at most, often sooner by tenant policy) — when one lapses, create a new secret and re-enter it on this form."})]}),j&&e.jsxs("p",{className:"flex items-start gap-1.5 text-sm text-red-400",children:[e.jsx(C,{className:"mt-0.5 h-4 w-4 shrink-0"}),j]})]}),e.jsxs("div",{className:"flex justify-end gap-3 border-t border-slate-800 p-5 sm:p-6",children:[e.jsx("button",{type:"button",onClick:t,disabled:u,className:"rounded-lg px-4 py-2 text-sm font-medium text-slate-400 transition-colors hover:bg-slate-800 hover:text-white disabled:opacity-50",children:"Cancel"}),e.jsx("button",{type:"button",onClick:b,disabled:u,className:"inline-flex items-center gap-2 rounded-lg bg-cyan-600 px-5 py-2 text-sm font-semibold text-white transition-colors hover:bg-cyan-500 disabled:cursor-not-allowed disabled:opacity-50",children:u?"Validating credential…":a?"Reconnect":"Connect"})]})]})})}rt.propTypes={existing:c.object,onClose:c.func.isRequired,onConnected:c.func.isRequired};function Zt(){const{getValidToken:a}=Z(),[t,o]=n.useState([]),[i,l]=n.useState(null),[x,g]=n.useState(!0),[y,T]=n.useState(null),[h,A]=n.useState(!1),[u,E]=n.useState(!1),{activeAccount:j}=lt(),p=(j?.account_type??"personal")==="personal",b=it(),[d]=ot(),[S,w]=n.useState(!1),[m,_]=n.useState(!1),[K,M]=n.useState(!1),[F,D]=n.useState(!1),[q,f]=n.useState(null),[N,L]=n.useState(null),[W,O]=n.useState(null),[$,X]=n.useState(!1),[G,H]=n.useState(""),[Q,Y]=n.useState(null),[U,R]=n.useState(null),P=n.useCallback(async()=>{try{const{integrations:r,eligibility:V}=await At(a);o(r),l(V),T(null)}catch(r){T(r.status===403?"Integrations are managed by account admins. Ask an admin of this account for access.":r.message||"Failed to load integrations.")}finally{g(!1)}},[a]);n.useEffect(()=>{P()},[P]);const z=i?i.eligible===!1:!1,I=async()=>{E(!0),R(null);try{const r=await Et(a);window.location.assign(r)}catch(r){E(!1),R({ok:!1,message:r.status===402?"Personal mailbox monitoring requires an active Seat License. Add a seat on your Account page, then connect again.":r.message||"Could not start the Microsoft sign-in."})}},ee=r=>{A(!1),!z&&(r==="gmail"&&w(!0),r==="outlook"&&_(!0),r==="outlook_personal"&&I(),r==="falcon"&&M(!0),r==="defender"&&D(!0))},re=t.find(r=>r.type==="falcon")||null,s=t.find(r=>r.type==="defender")||null;n.useEffect(()=>{const r=_t(d);r&&(R({ok:r.ok,message:r.message}),b("/integrations",{replace:!0}))},[d,b]);const k=async r=>{Y(r.id),R(null);try{const V=await It(a,r.type);R({ok:!0,message:"Directory re-synced.",sync:V?.sync}),await P()}catch(V){R({ok:!1,message:V.status===409?"This integration is not connected yet — run the connect flow first.":V.message||"Sync failed."})}finally{Y(null)}},v=async()=>{X(!0),H("");try{await Rt(a,W.id),await P(),O(null)}catch(r){H(r.message||"Failed to remove the integration.")}finally{X(!1)}};return e.jsxs("div",{className:"workspace-page min-h-screen bg-slate-950 px-4 pb-12 pt-24 text-white sm:px-6",children:[e.jsx(ct,{title:"Integrations | Blue Lantern Security",description:"Connect Blue Lantern to your email and workspace tools.",path:"/integrations"}),e.jsxs("div",{className:"mx-auto max-w-6xl space-y-6 sm:space-y-8",children:[e.jsxs("div",{className:"relative overflow-hidden rounded-3xl border border-slate-800 bg-slate-900 p-6 shadow-2xl sm:p-8",children:[e.jsx("div",{className:"pointer-events-none absolute -right-16 -top-16 h-64 w-64 roun
1ded-full bg-cyan-400/10 blur-3xl"}),e.jsxs("div",{className:"relative z-10 flex flex-col gap-4 md:flex-row md:items-start md:justify-between",children:[e.jsxs("div",{children:[e.jsxs("h1",{className:"flex items-center gap-3 text-2xl font-bold sm:text-3xl",children:[e.jsx(pe,{className:"h-7 w-7 shrink-0 text-cyan-300"}),"Integrations"]}),e.jsx("p",{className:"mt-2 max-w-2xl text-sm text-slate-400 sm:text-base",children:"Connect your email or endpoint provider to bring its security findings into one workspace."})]}),e.jsxs("button",{type:"button",onClick:()=>A(!0),"data-tour":"add-integration",className:"inline-flex shrink-0 items-center justify-center gap-2 self-start whitespace-nowrap rounded-lg bg-cyan-600 px-4 py-2 text-sm font-semibold text-white transition-colors hover:bg-cyan-500",children:[e.jsx(Ft,{className:"h-4 w-4"}),"Add Integration"]})]})]}),z&&e.jsxs("div",{className:"flex items-start gap-3 rounded-2xl border border-amber-500/20 bg-amber-500/5 p-5 text-sm",children:[e.jsx(Ve,{className:"mt-0.5 h-5 w-5 shrink-0 text-amber-400"}),e.jsxs("div",{className:"text-slate-300",children:[e.jsx("p",{className:"font-semibold text-amber-300",children:"Integrations require an active seat plan"}),e.jsxs("p",{className:"mt-1 text-slate-400",children:[i?.message||"Org-wide mailbox monitoring is licensed per seat. Your account has no active seat plan, so new integrations cannot be connected."," ",e.jsx(J,{to:"/organization",className:"text-cyan-400 hover:text-cyan-300 hover:underline",children:"Get seats"})," ","or see ",e.jsx(J,{to:"/pricing",className:"text-cyan-400 hover:text-cyan-300 hover:underline",children:"pricing"}),".",t.length>0&&e.jsx("span",{className:"block pt-1",children:"Your existing integration stays connected but ingestion is paused while no seat plan is active. Re-subscribing restores monitoring without reconnecting."})]})]})]}),e.jsxs("div",{className:"overflow-hidden rounded-2xl border border-slate-800 bg-slate-900",children:[U&&e.jsxs("div",{className:`space-y-3 border-b border-slate-800 px-5 py-4 text-sm sm:px-6 ${U.ok?"text-emerald-400":"text-red-400"}`,children:[e.jsxs("p",{className:"flex items-start gap-2",children:[U.ok?e.jsx(le,{className:"mt-0.5 h-4 w-4 shrink-0"}):e.jsx(C,{className:"mt-0.5 h-4 w-4 shrink-0"}),U.message]}),U.sync&&e.jsx(ce,{sync:U.sync})]}),e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-left",children:[e.jsx("thead",{className:`${!x&&!y&&t.length===0?"hidden":""} border-b border-slate-800 bg-slate-950/50 text-xs font-semibold uppercase tracking-wider text-slate-400`,children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-4 py-4 font-medium",children:"Integration"}),e.jsx("th",{className:"px-4 py-4 font-medium",children:"Status"}),e.jsx("th",{className:"hidden px-4 py-4 font-medium lg:table-cell",children:"Access"}),e.jsx("th",{className:"hidden px-4 py-4 font-medium md:table-cell",children:"Last Sync"}),e.jsx("th",{className:"px-4 py-4 text-right font-medium",children:"Actions"})]})}),e.jsxs("tbody",{className:"divide-y divide-slate-800/50",children:[x?e.jsx("tr",{children:e.jsx("td",{colSpan:"5",className:"p-8 text-center text-slate-500",children:"Loading…"})}):y?e.jsx("tr",{children:e.jsx("td",{colSpan:"5",className:"p-8 text-center text-slate-500",children:y})}):t.map(r=>{const V=We(r.type),B=r.settings||{};return e.jsxs("tr",{className:"transition-colors hover:bg-slate-800/30",children:[e.jsx("td",{className:"px-4 py-4",children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"rounded-lg bg-cyan-500/10 p-2 text-cyan-400",children:r.type==="outlook_personal"?e.jsx(Pe,{className:"h-4 w-4"}):r.type==="falcon"?e.jsx(je,{className:"h-4 w-4"}):r.type==="defender"?e.jsx(Ne,{className:"h-4 w-4"}):r.type==="outlook"?e.jsx(ye,{className:"h-4 w-4"}):e.jsx(ge,{className:"h-4 w-4"})}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"text-sm font-medium text-white",children:V?.label||r.type}),(B.domain||B.monitored_group||B.client_id)&&e.jsx("div",{className:"mt-0.5 truncate font-mono text-xs text-slate-500",title:B.monitored_group||B.domain||B.client_id,children:B.monitored_group||B.domain||B.client_id}),r.type==="outlook_personal"&&e.jsx("div",{className:"mt-0.5 text-xs text-slate-500",children:"Your mailbox · inbox only · read-only"}),r.type==="falcon"&&e.jsxs("div",{className:"mt-0.5 text-xs text-slate-500",children:["EDR agent health · ",B.region||"region unknown"," · daily scan"]}),r.type==="defender"&&e.jsx("div",{className:"mt-0.5 text-xs text-slate-500",children:"ED
1R agent health · daily scan"}),e.jsx(Xe,{integration:r}),e.jsx(Qe,{integration:r}),e.jsx(et,{integration:r}),e.jsxs("div",{className:"mt-1 space-y-0.5 lg:hidden",children:[e.jsxs("div",{className:"text-xs text-slate-500",children:[B.write_access?"Read + auto-quarantine":"Read-only",e.jsxs("span",{className:"md:hidden",children:[" · ",r.last_sync_at?`synced ${Ce(r.last_sync_at).toLowerCase()}`:"never synced"]})]}),e.jsx(fe,{expiresAt:r.credential_expires_at})]})]})]})}),e.jsxs("td",{className:"px-4 py-4",children:[e.jsx(Je,{status:r.status}),r.last_error&&(String(r.status).toLowerCase()==="error"||["falcon","defender"].includes(r.type))&&e.jsx("p",{className:`mt-1 max-w-[12rem] truncate text-xs ${String(r.status).toLowerCase()==="error"?"text-red-400/80":"text-amber-400/80"}`,title:r.last_error,children:r.last_error})]}),e.jsxs("td",{className:"hidden whitespace-nowrap px-4 py-4 text-sm text-slate-400 lg:table-cell",children:[B.write_access?"Read + auto-quarantine":"Read-only",e.jsx(fe,{expiresAt:r.credential_expires_at})]}),e.jsx("td",{className:"hidden whitespace-nowrap px-4 py-4 text-sm text-slate-400 md:table-cell",children:r.last_sync_at?Ce(r.last_sync_at):"Never"}),e.jsx("td",{className:"px-4 py-4",children:e.jsxs("div",{className:"flex flex-wrap items-center justify-end gap-2",children:[String(r.status).toLowerCase()==="pending"&&r.type==="outlook"&&e.jsxs("button",{type:"button",onClick:()=>f(r),className:"inline-flex shrink-0 items-center gap-1 whitespace-nowrap rounded-md border border-amber-400/30 bg-amber-500/10 px-2.5 py-1.5 text-xs font-medium text-amber-300 transition-colors hover:bg-amber-500/20",title:"Re-run the scope proof against the saved configuration",children:[e.jsx(se,{className:"h-3 w-3"}),"Verify"]}),r.type==="outlook_personal"&&["reauth_required","error","disconnected"].includes(String(r.status).toLowerCase())&&e.jsxs("button",{type:"button",onClick:I,disabled:u,className:"inline-flex shrink-0 items-center gap-1 whitespace-nowrap rounded-md border border-amber-400/30 bg-amber-500/10 px-2.5 py-1.5 text-xs font-medium text-amber-300 transition-colors hover:bg-amber-500/20 disabled:opacity-50",title:"Sign in with Microsoft again to resume monitoring",children:[e.jsx(Ie,{className:`h-3 w-3 ${u?"animate-spin":""}`}),"Reconnect"]}),["falcon","defender"].includes(r.type)&&e.jsxs("button",{type:"button",onClick:()=>r.type==="falcon"?M(!0):D(!0),className:`inline-flex shrink-0 items-center gap-1 whitespace-nowrap rounded-md border px-2.5 py-1.5 text-xs font-medium transition-colors ${["error","disconnected"].includes(String(r.status).toLowerCase())?"border-amber-400/30 bg-amber-500/10 text-amber-300 hover:bg-amber-500/20":"border-slate-600/60 bg-slate-800/60 text-slate-300 hover:bg-slate-700 hover:text-white"}`,title:r.type==="defender"?"Re-enter the credential — rotation, or after an expired client secret":"Re-enter the API credential — rotation, or after a credential error",children:[e.jsx(ie,{className:"h-3 w-3"}),"Reconnect"]}),String(r.status).toLowerCase()!=="pending"&&(r.type==="gmail"||r.type==="outlook")&&e.jsxs("button",{type:"button",onClick:()=>k(r),disabled:Q===r.id,className:"inline-flex shrink-0 items-center gap-1 whitespace-nowrap rounded-md border border-slate-600/60 bg-slate-800/60 px-2.5 py-1.5 text-xs font-medium text-slate-300 transition-colors hover:bg-slate-700 hover:text-white disabled:opacity-50",title:"Re-pull the directory now",children:[e.jsx(Ie,{className:`h-3 w-3 ${Q===r.id?"animate-spin":""}`}),"Sync"]}),(r.type==="gmail"||r.type==="outlook")&&e.jsxs("button",{type:"button",onClick:()=>L(r),className:"inline-flex shrink-0 items-center gap-1 whitespace-nowrap rounded-md border border-slate-600/60 bg-slate-800/60 px-2.5 py-1.5 text-xs font-medium text-slate-300 transition-colors hover:bg-slate-700 hover:text-white",children:[e.jsx(ze,{className:"h-3 w-3"}),"Settings"]}),e.jsxs("button",{type:"button",onClick:()=>{H(""),O(r)},className:"inline-flex shrink-0 items-center gap-1 whitespace-nowrap rounded-md border border-red-400/30 bg-red-500/10 px-2.5 py-1.5 text-xs font-medium text-red-300 transition-colors hover:bg-red-500/20",children:[e.jsx(Ue,{className:"h-3 w-3"}),"Remove"]})]})})]},r.id)}),!x&&!y&&t.length===0&&e.jsx("tr",{children:e.jsx("td",{colSpan:"5",className:"p-12 text-center text-slate-500",children:e.jsxs("div",{className:"setup-empty",children:[e.jsx(pe,{size:28}),e.jsx("h2",{children:"Connect your first integration"}),e.jsx("p",{children:"Choose a provider. The guided setup explains the access required before you connect."}),e.jsx("div",{className:"setup-choice-grid integrations-choices",children:$e.map(r=>{const V=r.personal&&!p;return e.jsxs("button",{type:"button",disabled:!r.available||z||V,onClick:()=>ee(r.type),children:[e.jsx("strong",{children:r.label}),e.jsx("span",{children:r.description}),e.jsx("b",{children:r.available?z?"Requires seat plan":V?"Personal accounts only":r.personal?"Continue with Microsoft →":"Start setup →":"Coming soon"})]},r.type)})}),e.jsxs("p",{className:"setup-footnote",children:["For browser extensions and device agents, ",e.jsx(J,{to:"/monitoring-hub?view=monitors",children:"set up a monitor"}),"."]})]})})})]})]})})]})]}),h&&e.jsx(Ze,{onClose:()=>A(!1),onPick:ee,locked:z,personalAccount:p}),S&&e.jsx(He,{onClose:()=>w(!1),onConnected:P}),m&&e.jsx(Ye,{onClose:()=>_(!1),onConnected:P}),K&&e.jsx(nt,{existing:re,onClose:()=>M(!1),onConnected:()=>{M(!1),R({ok:!0,message:"CrowdStrike Falcon connected. A health run per device appears in the Monitoring Hub after each daily scan."}),P()}}),F&&e.jsx(rt,{existing:s,onClose:()=>D(!1),onConnected:()=>{D(!1),R({ok:!0,message:"Microsoft Defender connected. A health run per device appears in the Monitoring Hub after each daily scan."}),P()}}),q&&e.jsx(at,{integration:q,onClose:()=>f(null),onRefresh:P}),N&&e.jsx(tt,{integration:N,onClose:()=>L(null),onSaved:P}),W&&e.jsx(st,{integration:W,loading:$,error:G,onCancel:()=>{$||O(null)},onConfirm:v})]})}
1export{Zt as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.