veza/apps/web/dist_verification/assets/SessionsPage-Bf46A7Ge.js
senke 04c25aa24f Phase 2 stabilisation: code mort, Modal→Dialog, feature flags, tests, router split, Rust legacy
Bloc A - Code mort:
- Suppression Studio (components, views, features)
- Suppression gamification + services mock (projectService, storageService, gamificationService)
- Mise à jour Sidebar, Navbar, locales

Bloc B - Frontend:
- Suppression modal.tsx deprecated, Modal.stories (doublon Dialog)
- Feature flags: PLAYLIST_SEARCH, PLAYLIST_RECOMMENDATIONS, ROLE_MANAGEMENT = true
- Suppression 19 tests orphelins, retrait exclusions vitest.config

Bloc C - Backend:
- Extraction routes_auth.go depuis router.go

Bloc D - Rust:
- Suppression security_legacy.rs (code mort, patterns déjà dans security/)
2026-02-14 17:23:32 +01:00

1 line
9.9 KiB
JavaScript

import{a as r,j as s}from"./vendor-react-yWUy5XPk.js";import{C as S}from"./confirmation-dialog-DS4X89Bi.js";import{g as y,p as b,l as N,B as A,L,k as C,C as E,b as I,d as M,e as F,f as O,S as m}from"./index-CYK_b1Uz.js";import{aw as U,G as B,ac as z,i as $,au as G,ax as H,ay as Y,at as q,W as J}from"./vendor-icons-DJFb1Tiw.js";import"./vendor-CveO81sn.js";import"./vendor-security-DsrNJhpn.js";import"./vendor-router-BNNHboN9.js";import"./vendor-tanstack-kPY9uK0s.js";import"./vendor-http-Cz8wfb0q.js";import"./vendor-utils-DtoSyhX2.js";import"./vendor-motion-B3XPS3Jc.js";import"./vendor-i18n-CMcqpBLz.js";function V(e){const i=e.toLowerCase(),t={deviceType:"unknown",os:"Unknown",browser:"Unknown"};if(i.includes("mobile")||i.includes("android")||i.includes("iphone")?t.deviceType="mobile":i.includes("tablet")||i.includes("ipad")?t.deviceType="tablet":t.deviceType="desktop",i.includes("windows")){t.os="Windows";const a=i.match(/windows nt (\d+\.\d+)/);if(a){const n=a[1];n==="10.0"?t.osVersion="10":n==="6.3"?t.osVersion="8.1":n==="6.2"?t.osVersion="8":n==="6.1"?t.osVersion="7":t.osVersion=n}}else if(i.includes("mac os x")||i.includes("macintosh")){t.os="macOS";const a=i.match(/mac os x (\d+[._]\d+)/);a?.[1]&&(t.osVersion=a[1].replace("_","."))}else if(i.includes("linux"))t.os="Linux";else if(i.includes("android")){t.os="Android";const a=i.match(/android (\d+\.\d+)/);a&&(t.osVersion=a[1])}else if(i.includes("ios")||i.includes("iphone")||i.includes("ipad")){t.os="iOS";const a=i.match(/os (\d+[._]\d+)/);a?.[1]&&(t.osVersion=a[1].replace("_","."))}if(i.includes("edg/")){t.browser="Microsoft Edge";const a=i.match(/edg\/(\d+\.\d+)/);a&&(t.browserVersion=a[1])}else if(i.includes("chrome/")&&!i.includes("edg/")){t.browser="Chrome";const a=i.match(/chrome\/(\d+\.\d+)/);a&&(t.browserVersion=a[1])}else if(i.includes("firefox/")){t.browser="Firefox";const a=i.match(/firefox\/(\d+\.\d+)/);a&&(t.browserVersion=a[1])}else if(i.includes("safari/")&&!i.includes("chrome/")){t.browser="Safari";const a=i.match(/version\/(\d+\.\d+)/);a&&(t.browserVersion=a[1])}else if(i.includes("opera/")||i.includes("opr/")){t.browser="Opera";const a=i.match(/(?:opera|opr)\/(\d+\.\d+)/);a&&(t.browserVersion=a[1])}if(i.includes("iphone"))i.match(/iphone\s+os\s+(\d+[._]\d+)/)&&(t.deviceModel="iPhone");else if(i.includes("ipad"))t.deviceModel="iPad";else if(i.includes("android")){const a=i.match(/android.*?;\s*([^)]+)\)/);a?.[1]&&(t.deviceModel=a[1].trim())}return t}function K(e){const i=[];return e.deviceModel&&i.push(e.deviceModel),i.push(e.os),e.osVersion&&i.push(e.osVersion),i.push(e.browser),e.browserVersion&&i.push(e.browserVersion),i.join(" • ")}function Q(e){if(!e)return"Unknown location";const i=[];return e.city&&i.push(e.city),e.region&&i.push(e.region),e.country&&i.push(e.country),i.length>0?i.join(", "):"Unknown location"}function X(e){return e==="127.0.0.1"||e==="localhost"||e.startsWith("192.168.")||e.startsWith("10.")||e.startsWith("172.16.")||e.startsWith("172.17.")||e.startsWith("172.18.")||e.startsWith("172.19.")||e.startsWith("172.20.")||e.startsWith("172.21.")||e.startsWith("172.22.")||e.startsWith("172.23.")||e.startsWith("172.24.")||e.startsWith("172.25.")||e.startsWith("172.26.")||e.startsWith("172.27.")||e.startsWith("172.28.")||e.startsWith("172.29.")||e.startsWith("172.30.")||e.startsWith("172.31.")}function Z(e){const[i,t]=r.useState(e?.initialSessions??[]),[a,n]=r.useState(e?.isLoading??!0),[g,h]=r.useState(null),[p,j]=r.useState(!1),[w,c]=r.useState(null),[d,f]=r.useState(null),[k,x]=r.useState(!1),o=r.useCallback(async()=>{try{n(!0),c(null);const l=await y.get("/auth/sessions");t(l.data.sessions)}catch(l){const u=b(l);N.error("Failed to fetch sessions",{message:u.message}),c(u.message)}finally{n(!1)}},[]);r.useEffect(()=>{if(e?.initialSessions!==void 0){t(e.initialSessions),n(!1);return}if(e?.isLoading===!0){n(!0);return}o()},[o,e?.initialSessions,e?.isLoading]);const v=r.useCallback(l=>{f(l)},[]),W=r.useCallback(async()=>{if(d)try{h(d),c(null),await y.delete(`/auth/sessions/${d}`),await o(),f(null)}catch(l){const u=b(l);N.error("Failed to revoke session",{message:u.message,sessionId:d}),c(u.message)}finally{h(null)}},[d,o]),_=r.useCallback(()=>{x(!0)},[]),P=r.useCallback(async()=>{try{j(!0),c(null),await y.delete("/auth/sessions"),await o(),x(!1)}catch(l){const u=b(l);N.error("Failed to revoke sessions",{message:u.message}),c(u.message)}finally{j(!1)}},[o]),D=r.useCallback(()=>f(null),[]),T=r.useCallback(()=>x(!1),[]);return{sessions:i,loading:a,error:w,revoking:g,revokingAll:p,sessionToRevoke:d,showRevokeAllDialog:k,fetchSessions:o,handleRevokeClick:v,revokeSession:W,handleRevokeAllClick:_,revokeAllOther:P,closeRevokeDialog:D,closeRevokeAllDialog:T}}function ee(){return s.jsxs("div",{children:[s.jsx("h1",{className:"text-heading-1",children:"Active Sessions"}),s.jsx("p",{className:"text-muted-foreground",children:"Manage your active sessions and sign out from other devices"})]})}function se({message:e}){return s.jsx("div",{className:"bg-destructive/10 text-destructive px-4 py-4 rounded-md",children:e})}function ie({disabled:e,loading:i,onClick:t}){return s.jsx("div",{className:"flex justify-end",children:s.jsx(A,{onClick:t,disabled:e,variant:"destructive",children:i?s.jsxs(s.Fragment,{children:[s.jsx(L,{size:"sm",inline:!0,className:"mr-2"}),"Revoking..."]}):s.jsxs(s.Fragment,{children:[s.jsx(U,{className:"mr-2 h-4 w-4"}),"Revoke All Other Sessions"]})})})}function ae(){return s.jsx("div",{className:"text-center py-8 text-muted-foreground",children:"No active sessions found."})}function te(e){switch(e){case"mobile":return s.jsx(q,{className:"h-5 w-5"});case"tablet":return s.jsx(Y,{className:"h-5 w-5"});case"desktop":return s.jsx(H,{className:"h-5 w-5"});default:return s.jsx(G,{className:"h-5 w-5"})}}function R(e){const i=new Date(e);return new Intl.DateTimeFormat("en-US",{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}).format(i)}function ne({session:e,isRevoking:i,onRevokeClick:t}){const a=e.device_info??V(e.user_agent),n=e.location_info;return s.jsxs("div",{className:`flex items-center justify-between p-4 border rounded-lg ${e.is_current?"border-primary bg-primary/5":"border-border"}`,children:[s.jsxs("div",{className:"flex items-start gap-4 flex-1",children:[s.jsx("div",{className:"mt-1",children:te(a.deviceType)}),s.jsxs("div",{className:"flex-1 space-y-2",children:[s.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[s.jsx("p",{className:"font-medium",children:K(a)}),e.is_current&&s.jsx(C,{variant:"default",className:"bg-primary text-primary-foreground",children:"Current Session"}),s.jsx(C,{variant:"secondary",className:"capitalize",children:a.deviceType})]}),s.jsxs("div",{className:"flex flex-wrap gap-4 text-sm text-muted-foreground",children:[s.jsxs("div",{className:"flex items-center gap-1",children:[s.jsx(B,{className:"h-4 w-4"}),s.jsx("span",{children:e.ip_address||"Unknown IP"})]}),n&&s.jsxs("div",{className:"flex items-center gap-1",children:[s.jsx(z,{className:"h-4 w-4"}),s.jsx("span",{children:Q(n)})]}),s.jsxs("div",{children:[s.jsx("span",{className:"font-medium",children:"Created:"})," ",R(e.created_at)]}),e.last_activity&&s.jsxs("div",{children:[s.jsx("span",{className:"font-medium",children:"Last activity:"})," ",R(e.last_activity)]})]}),a.browserVersion&&s.jsxs("div",{className:"text-xs text-muted-foreground",children:[a.browser," ",a.browserVersion,a.osVersion&&`${a.os} ${a.osVersion}`]})]})]}),!e.is_current&&s.jsx(A,{onClick:()=>t(e.id),disabled:i,variant:"destructive",size:"sm",children:i?s.jsxs(s.Fragment,{children:[s.jsx(L,{size:"sm",inline:!0,className:"mr-2"}),"Revoking..."]}):s.jsxs(s.Fragment,{children:[s.jsx($,{className:"mr-2 h-4 w-4"}),"Revoke"]})})]})}function re({sessions:e,revoking:i,onRevokeClick:t}){return s.jsxs(E,{children:[s.jsxs(I,{children:[s.jsxs(M,{className:"flex items-center gap-2",children:[s.jsx(J,{className:"h-5 w-5"}),"Sessions (",e.length,")"]}),s.jsx(F,{children:"These are the devices where you're currently signed in"})]}),s.jsx(O,{children:e.length===0?s.jsx(ae,{}):s.jsx("div",{className:"space-y-4",children:e.map(a=>s.jsx(ne,{session:a,isRevoking:i===a.id,onRevokeClick:t},a.id))})})]})}function oe(){return s.jsx("div",{className:"flex items-center justify-center min-h-layout-page-sm",children:s.jsxs("div",{className:"space-y-6 w-full max-w-2xl",children:[s.jsx(m,{className:"h-8 w-64 rounded"}),s.jsx(m,{className:"h-4 w-96 rounded"}),s.jsx("div",{className:"flex justify-end",children:s.jsx(m,{className:"h-10 w-56 rounded"})}),s.jsxs("div",{className:"rounded-lg border bg-card p-6 space-y-4",children:[s.jsx(m,{className:"h-6 w-32 rounded"}),s.jsx(m,{className:"h-4 w-72 rounded"}),s.jsxs("div",{className:"space-y-4 pt-4",children:[s.jsx(m,{className:"h-24 rounded-lg"}),s.jsx(m,{className:"h-24 rounded-lg"})]})]})]})})}function we(e){const i=e?{initialSessions:e.initialSessions,isLoading:e.isLoading}:void 0,{sessions:t,loading:a,error:n,revoking:g,revokingAll:h,sessionToRevoke:p,showRevokeAllDialog:j,handleRevokeClick:w,revokeSession:c,handleRevokeAllClick:d,revokeAllOther:f,closeRevokeDialog:k,closeRevokeAllDialog:x}=Z(i),o=r.useMemo(()=>t.map(v=>({...v,device_info:V(v.user_agent),location_info:X(v.ip_address)?{country:"Local",region:"Network",city:"Private IP"}:null})),[t]);return a?s.jsx(oe,{}):s.jsxs("div",{className:"space-y-6",children:[s.jsx(ee,{}),n&&s.jsx(se,{message:n}),s.jsx(ie,{disabled:h||t.length<=1,loading:h,onClick:d}),s.jsx(re,{sessions:o,revoking:g,onRevokeClick:w}),s.jsx(S,{open:!!p,onClose:k,onConfirm:c,title:"Revoke Session",description:"Are you sure you want to revoke this session? The user will be logged out from this device.",confirmLabel:"Revoke",cancelLabel:"Cancel",variant:"destructive",isLoading:!!g}),s.jsx(S,{open:j,onClose:x,onConfirm:f,title:"Revoke All Other Sessions",description:"Are you sure you want to revoke all other sessions? You will remain logged in on this device, but all other devices will be logged out.",confirmLabel:"Revoke All",cancelLabel:"Cancel",variant:"destructive",isLoading:h})]})}export{we as SessionsPage,we as default};