<mxfile host="app.diagrams.net" type="device">
  <diagram name="sequencia-login" id="sequencia-login">
    <mxGraphModel dx="1200" dy="800" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1600" pageHeight="1200" math="0" shadow="0">
      <root>
        <mxCell id="0"/>
        <mxCell id="1" parent="0"/>
        <mxCell id="n2" value="Busca-Busca — Sequência: login social (OIDC + PKCE) · refresh · logout" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=17;fontColor=#222222;fontStyle=1;" vertex="1" parent="1"><mxGeometry x="40" y="20" width="1200" height="24" as="geometry"/></mxCell>
        <mxCell id="n3" value="&lt;b&gt;Frontend (Angular)&lt;/b&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5f5f0;strokeColor=#3aa89a;fontSize=11;align=center;verticalAlign=middle;" vertex="1" parent="1"><mxGeometry x="75" y="60" width="190" height="40" as="geometry"/></mxCell>
        <mxCell id="n4" value="" style="html=1;endArrow=none;dashed=1;strokeColor=#aaaaaa;" edge="1" parent="1"><mxGeometry relative="1" as="geometry"><mxPoint x="170" y="100" as="sourcePoint"/><mxPoint x="170" y="930" as="targetPoint"/></mxGeometry></mxCell>
        <mxCell id="n5" value="&lt;b&gt;Backend (Spring Security)&lt;/b&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=11;align=center;verticalAlign=middle;" vertex="1" parent="1"><mxGeometry x="405" y="60" width="190" height="40" as="geometry"/></mxCell>
        <mxCell id="n6" value="" style="html=1;endArrow=none;dashed=1;strokeColor=#aaaaaa;" edge="1" parent="1"><mxGeometry relative="1" as="geometry"><mxPoint x="500" y="100" as="sourcePoint"/><mxPoint x="500" y="930" as="targetPoint"/></mxGeometry></mxCell>
        <mxCell id="n7" value="&lt;b&gt;IdP (Google/GitHub)&lt;/b&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;fontSize=11;align=center;verticalAlign=middle;" vertex="1" parent="1"><mxGeometry x="735" y="60" width="190" height="40" as="geometry"/></mxCell>
        <mxCell id="n8" value="" style="html=1;endArrow=none;dashed=1;strokeColor=#aaaaaa;" edge="1" parent="1"><mxGeometry relative="1" as="geometry"><mxPoint x="830" y="100" as="sourcePoint"/><mxPoint x="830" y="930" as="targetPoint"/></mxGeometry></mxCell>
        <mxCell id="n9" value="&lt;b&gt;PostgreSQL&lt;/b&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=11;align=center;verticalAlign=middle;" vertex="1" parent="1"><mxGeometry x="1025" y="60" width="190" height="40" as="geometry"/></mxCell>
        <mxCell id="n10" value="" style="html=1;endArrow=none;dashed=1;strokeColor=#aaaaaa;" edge="1" parent="1"><mxGeometry relative="1" as="geometry"><mxPoint x="1120" y="100" as="sourcePoint"/><mxPoint x="1120" y="930" as="targetPoint"/></mxGeometry></mxCell>
        <mxCell id="n11" value="1 · Login" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=11;fontColor=#8a56ac;fontStyle=1;" vertex="1" parent="1"><mxGeometry x="36" y="122" width="130" height="24" as="geometry"/></mxCell>
        <mxCell id="n12" value="GET /oauth2/authorization/{provedor}" style="html=1;rounded=0;endArrow=block;startArrow=none;strokeColor=#555555;fontSize=10;verticalAlign=bottom;" edge="1" parent="1"><mxGeometry relative="1" as="geometry"><mxPoint x="170" y="154" as="sourcePoint"/><mxPoint x="500" y="154" as="targetPoint"/></mxGeometry></mxCell>
        <mxCell id="n13" value="302 → provedor (authorize + PKCE + state)" style="html=1;rounded=0;endArrow=block;startArrow=none;strokeColor=#555555;dashed=1;fontSize=10;verticalAlign=bottom;" edge="1" parent="1"><mxGeometry relative="1" as="geometry"><mxPoint x="500" y="192" as="sourcePoint"/><mxPoint x="170" y="192" as="targetPoint"/></mxGeometry></mxCell>
        <mxCell id="n14" value="login + consentimento" style="html=1;rounded=0;endArrow=block;startArrow=none;strokeColor=#555555;fontSize=10;verticalAlign=bottom;" edge="1" parent="1"><mxGeometry relative="1" as="geometry"><mxPoint x="170" y="230" as="sourcePoint"/><mxPoint x="830" y="230" as="targetPoint"/></mxGeometry></mxCell>
        <mxCell id="n15" value="302 code → /login/oauth2/code/{provedor}" style="html=1;rounded=0;endArrow=block;startArrow=none;strokeColor=#555555;dashed=1;fontSize=10;verticalAlign=bottom;" edge="1" parent="1"><mxGeometry relative="1" as="geometry"><mxPoint x="830" y="268" as="sourcePoint"/><mxPoint x="170" y="268" as="targetPoint"/></mxGeometry></mxCell>
        <mxCell id="n16" value="GET /login/oauth2/code (code)" style="html=1;rounded=0;endArrow=block;startArrow=none;strokeColor=#555555;fontSize=10;verticalAlign=bottom;" edge="1" parent="1"><mxGeometry relative="1" as="geometry"><mxPoint x="170" y="306" as="sourcePoint"/><mxPoint x="500" y="306" as="targetPoint"/></mxGeometry></mxCell>
        <mxCell id="n17" value="troca code → tokens (valida id_token/nonce)" style="html=1;rounded=0;endArrow=block;startArrow=none;strokeColor=#555555;fontSize=10;verticalAlign=bottom;" edge="1" parent="1"><mxGeometry relative="1" as="geometry"><mxPoint x="500" y="344" as="sourcePoint"/><mxPoint x="830" y="344" as="targetPoint"/></mxGeometry></mxCell>
        <mxCell id="n18" value="id_token + userinfo" style="html=1;rounded=0;endArrow=block;startArrow=none;strokeColor=#555555;dashed=1;fontSize=10;verticalAlign=bottom;" edge="1" parent="1"><mxGeometry relative="1" as="geometry"><mxPoint x="830" y="382" as="sourcePoint"/><mxPoint x="500" y="382" as="targetPoint"/></mxGeometry></mxCell>
        <mxCell id="n19" value="upsert usuario (provedor+provedor_id) · cria refresh (familia)" style="html=1;rounded=0;endArrow=block;startArrow=none;strokeColor=#555555;fontSize=10;verticalAlign=bottom;" edge="1" parent="1"><mxGeometry relative="1" as="geometry"><mxPoint x="500" y="420" as="sourcePoint"/><mxPoint x="1120" y="420" as="targetPoint"/></mxGeometry></mxCell>
        <mxCell id="n20" value="302 app + Set-Cookie ACCESS+REFRESH (HttpOnly)" style="html=1;rounded=0;endArrow=block;startArrow=none;strokeColor=#555555;dashed=1;fontSize=10;verticalAlign=bottom;" edge="1" parent="1"><mxGeometry relative="1" as="geometry"><mxPoint x="500" y="458" as="sourcePoint"/><mxPoint x="170" y="458" as="targetPoint"/></mxGeometry></mxCell>
        <mxCell id="n21" value="GET /api/v1/auth/me" style="html=1;rounded=0;endArrow=block;startArrow=none;strokeColor=#555555;fontSize=10;verticalAlign=bottom;" edge="1" parent="1"><mxGeometry relative="1" as="geometry"><mxPoint x="170" y="496" as="sourcePoint"/><mxPoint x="500" y="496" as="targetPoint"/></mxGeometry></mxCell>
        <mxCell id="n22" value="200 · Usuario" style="html=1;rounded=0;endArrow=block;startArrow=none;strokeColor=#555555;dashed=1;fontSize=10;verticalAlign=bottom;" edge="1" parent="1"><mxGeometry relative="1" as="geometry"><mxPoint x="500" y="534" as="sourcePoint"/><mxPoint x="170" y="534" as="targetPoint"/></mxGeometry></mxCell>
        <mxCell id="n23" value="2 · Renovação" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=11;fontColor=#8a56ac;fontStyle=1;" vertex="1" parent="1"><mxGeometry x="36" y="566" width="130" height="24" as="geometry"/></mxCell>
        <mxCell id="n24" value="request protegido (ACCESS expirado)" style="html=1;rounded=0;endArrow=block;startArrow=none;strokeColor=#555555;fontSize=10;verticalAlign=bottom;" edge="1" parent="1"><mxGeometry relative="1" as="geometry"><mxPoint x="170" y="598" as="sourcePoint"/><mxPoint x="500" y="598" as="targetPoint"/></mxGeometry></mxCell>
        <mxCell id="n25" value="401" style="html=1;rounded=0;endArrow=block;startArrow=none;strokeColor=#555555;dashed=1;fontSize=10;verticalAlign=bottom;" edge="1" parent="1"><mxGeometry relative="1" as="geometry"><mxPoint x="500" y="636" as="sourcePoint"/><mxPoint x="170" y="636" as="targetPoint"/></mxGeometry></mxCell>
        <mxCell id="n26" value="POST /api/v1/auth/refresh (cookie REFRESH)" style="html=1;rounded=0;endArrow=block;startArrow=none;strokeColor=#555555;fontSize=10;verticalAlign=bottom;" edge="1" parent="1"><mxGeometry relative="1" as="geometry"><mxPoint x="170" y="674" as="sourcePoint"/><mxPoint x="500" y="674" as="targetPoint"/></mxGeometry></mxCell>
        <mxCell id="n27" value="valida hash · rotaciona (revoga antigo, detecta reúso)" style="html=1;rounded=0;endArrow=block;startArrow=none;strokeColor=#555555;fontSize=10;verticalAlign=bottom;" edge="1" parent="1"><mxGeometry relative="1" as="geometry"><mxPoint x="500" y="712" as="sourcePoint"/><mxPoint x="1120" y="712" as="targetPoint"/></mxGeometry></mxCell>
        <mxCell id="n28" value="204 + Set-Cookie novos ACCESS+REFRESH" style="html=1;rounded=0;endArrow=block;startArrow=none;strokeColor=#555555;dashed=1;fontSize=10;verticalAlign=bottom;" edge="1" parent="1"><mxGeometry relative="1" as="geometry"><mxPoint x="500" y="750" as="sourcePoint"/><mxPoint x="170" y="750" as="targetPoint"/></mxGeometry></mxCell>
        <mxCell id="n29" value="3 · Logout" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=11;fontColor=#8a56ac;fontStyle=1;" vertex="1" parent="1"><mxGeometry x="36" y="782" width="130" height="24" as="geometry"/></mxCell>
        <mxCell id="n30" value="POST /api/v1/auth/logout" style="html=1;rounded=0;endArrow=block;startArrow=none;strokeColor=#555555;fontSize=10;verticalAlign=bottom;" edge="1" parent="1"><mxGeometry relative="1" as="geometry"><mxPoint x="170" y="814" as="sourcePoint"/><mxPoint x="500" y="814" as="targetPoint"/></mxGeometry></mxCell>
        <mxCell id="n31" value="revoga refresh (familia / todos dispositivos)" style="html=1;rounded=0;endArrow=block;startArrow=none;strokeColor=#555555;fontSize=10;verticalAlign=bottom;" edge="1" parent="1"><mxGeometry relative="1" as="geometry"><mxPoint x="500" y="852" as="sourcePoint"/><mxPoint x="1120" y="852" as="targetPoint"/></mxGeometry></mxCell>
        <mxCell id="n32" value="204" style="html=1;rounded=0;endArrow=block;startArrow=none;strokeColor=#555555;dashed=1;fontSize=10;verticalAlign=bottom;" edge="1" parent="1"><mxGeometry relative="1" as="geometry"><mxPoint x="500" y="890" as="sourcePoint"/><mxPoint x="170" y="890" as="targetPoint"/></mxGeometry></mxCell>
      </root>
    </mxGraphModel>
  </diagram>
</mxfile>
