Files
genesis-2/notebooks/supabase-security.ipynb
T
alexrg d4ceac77a9
Deploy Function / deploy (push) Failing after 14s
Deploy Migrations to Production / deploy (push) Failing after 8s
feat: add logging for JWT refresh and session management in Supabase security notebook
2026-03-02 14:13:28 -06:00

16 KiB

import { createClient } from "@supabase/supabase-js";
const supabaseUrl = Deno.env.get("SUPABASE_URL") || env.SUPABASE_URL;
const supabaseKey = Deno.env.get("SUPABASE_ANON_KEY") || env.SUPABASE_ANON_KEY;

const supabase = createClient(supabaseUrl, supabaseKey);
const supa = await supabase.auth.signInWithPassword({
    email: 'guillermo.arrieta@lasalle.mx',
    password: 'admin',
});
 
import { jwtDecode } from "npm:jwt-decode";

const listener = supabase.auth.onAuthStateChange(async (event, session) => {
  if (session) {
    const jwt = jwtDecode(session.access_token);
    console.log(event, jwt);
    // store in the session
    localStorage.setItem("jwt", JSON.stringify(session));

  }
});

listener;
{
  access_token: "eyJhbGciOiJFUzI1NiIsImtpZCI6ImI4MTI2OWYxLTIxZDgtNGYyZS1iNzE5LWMyMjQwYTg0MGQ5MCIsInR5cCI6IkpXVCJ9.eyJhYWwiOiJhYWwxIiwiYW1yIjpbeyJtZXRob2QiOiJwYXNzd29yZCIsInRpbWVzdGFtcCI6MTc3MjQ3MzI3MX1dLCJhcHBfbWV0YWRhdGEiOnsicHJvdmlkZXIiOiJlbWFpbCIsInByb3ZpZGVycyI6WyJlbWFpbCJdfSwiYXVkIjoiYXV0aGVudGljYXRlZCIsImVtYWlsIjoiZ3VpbGxlcm1vLmFycmlldGFAbGFzYWxsZS5teCIsImV4cCI6MTc3MjQ3Njg3MSwiZmVhdHVyZV94Ijp0cnVlLCJpYXQiOjE3NzI0NzMyNzEsImlzX2Fub255bW91cyI6ZmFsc2UsImlzcyI6Imh0dHA6Ly8xMjcuMC4wLjE6NTQzMjEvYXV0aC92MSIsInBob25lIjoiIiwicm9sZSI6ImF1dGhlbnRpY2F0ZWQiLCJzZXNzaW9uX2lkIjoiZjc2ZjRkZGYtZTcxOS00NjRiLWIwYWUtODBhNmIxMjBlZmE0Iiwic3ViIjoiOTVkMWYzODEtNzAyMy00ZjMzLWJjNTQtMDhjY2QwOGFiZjQxIiwidGVuYW50X2lkIjoibG9jYWwtZGV2LXRlbmFudCIsInVzZXJfbWV0YWRhdGEiOnsiZW1haWxfdmVyaWZpZWQiOnRydWV9fQ.LEXrbBNetdCb8zfCiLcXhJg3EmX6XuE4cYOaFmYg1PhvvNI5XorbJQHhb4SQVggQDOauIqqkMRsK64GK1nheIw",
  token_type: "bearer",
  expires_in: 3600,
  expires_at: 1772476871,
  refresh_token: "lwgtrzw2tpzl",
  user: {
    id: "95d1f381-7023-4f33-bc54-08ccd08abf41",
    aud: "authenticated",
    role: "authenticated",
    email: "guillermo.arrieta@lasalle.mx",
    email_confirmed_at: "2026-01-13T14:54:39.096101Z",
    phone: "",
    confirmed_at: "2026-01-13T14:54:39.096101Z",
    last_sign_in_at: "2026-03-02T17:41:10.98658403Z",
    app_metadata: { provider: "email", providers: [ "email" ] },
    user_metadata: { email_verified: true },
    identities: [
      {
        identity_id: "b2f3094d-a29b-42b5-be69-3397282ffcd7",
        id: "95d1f381-7023-4f33-bc54-08ccd08abf41",
        user_id: "95d1f381-7023-4f33-bc54-08ccd08abf41",
        identity_data: {
          email: "guillermo.arrieta@lasalle.mx",
          email_verified: false,
          phone_verified: false,
          sub: "95d1f381-7023-4f33-bc54-08ccd08abf41"
        },
        provider: "email",
        last_sign_in_at: "2026-01-13T14:54:39.085382Z",
        created_at: "2026-01-13T14:54:39.08544Z",
        updated_at: "2026-01-13T14:54:39.08544Z",
        email: "guillermo.arrieta@lasalle.mx"
      }
    ],
    created_at: "2026-01-13T14:54:39.081453Z",
    updated_at: "2026-03-02T17:41:11.002577Z",
    is_anonymous: false
  },
  weak_password: {
    message: "Password should be at least 6 characters.",
    reasons: [ "length" ]
  }
}
{
  data: {
    subscription: {
      id: Symbol("auth-callback"),
      callback: [AsyncFunction (anonymous)],
      unsubscribe: [Function: unsubscribe]
    }
  }
}
TOKEN_REFRESHED {
  aal: "aal1",
  amr: [ { method: "password", timestamp: 1772473271 } ],
  app_metadata: { provider: "email", providers: [ "email" ] },
  aud: "authenticated",
  email: "guillermo.arrieta@lasalle.mx",
  exp: 1772480381,
  feature_x: true,
  iat: 1772476781,
  is_anonymous: false,
  iss: "http://127.0.0.1:54321/auth/v1",
  phone: "",
  role: "authenticated",
  session_id: "f76f4ddf-e719-464b-b0ae-80a6b120efa4",
  sub: "95d1f381-7023-4f33-bc54-08ccd08abf41",
  tenant_id: "local-dev-tenant",
  user_metadata: { email_verified: true }
}
{
  access_token: "eyJhbGciOiJFUzI1NiIsImtpZCI6ImI4MTI2OWYxLTIxZDgtNGYyZS1iNzE5LWMyMjQwYTg0MGQ5MCIsInR5cCI6IkpXVCJ9.eyJhYWwiOiJhYWwxIiwiYW1yIjpbeyJtZXRob2QiOiJwYXNzd29yZCIsInRpbWVzdGFtcCI6MTc3MjQ3MzI3MX1dLCJhcHBfbWV0YWRhdGEiOnsicHJvdmlkZXIiOiJlbWFpbCIsInByb3ZpZGVycyI6WyJlbWFpbCJdfSwiYXVkIjoiYXV0aGVudGljYXRlZCIsImVtYWlsIjoiZ3VpbGxlcm1vLmFycmlldGFAbGFzYWxsZS5teCIsImV4cCI6MTc3MjQ4MDM4MSwiZmVhdHVyZV94Ijp0cnVlLCJpYXQiOjE3NzI0NzY3ODEsImlzX2Fub255bW91cyI6ZmFsc2UsImlzcyI6Imh0dHA6Ly8xMjcuMC4wLjE6NTQzMjEvYXV0aC92MSIsInBob25lIjoiIiwicm9sZSI6ImF1dGhlbnRpY2F0ZWQiLCJzZXNzaW9uX2lkIjoiZjc2ZjRkZGYtZTcxOS00NjRiLWIwYWUtODBhNmIxMjBlZmE0Iiwic3ViIjoiOTVkMWYzODEtNzAyMy00ZjMzLWJjNTQtMDhjY2QwOGFiZjQxIiwidGVuYW50X2lkIjoibG9jYWwtZGV2LXRlbmFudCIsInVzZXJfbWV0YWRhdGEiOnsiZW1haWxfdmVyaWZpZWQiOnRydWV9fQ.28CQUM9O7Cn1DlbMsLLaN-19uDmEGC_NvLRL6S3-Z3ym3T5gQ5OXiJ6_NlyblMJfJOQdMo88uGRIAZt9PwkE6A",
  token_type: "bearer",
  expires_in: 3600,
  expires_at: 1772480381,
  refresh_token: "363vd67k2taw",
  user: {
    id: "95d1f381-7023-4f33-bc54-08ccd08abf41",
    aud: "authenticated",
    role: "authenticated",
    email: "guillermo.arrieta@lasalle.mx",
    email_confirmed_at: "2026-01-13T14:54:39.096101Z",
    phone: "",
    confirmed_at: "2026-01-13T14:54:39.096101Z",
    last_sign_in_at: "2026-03-02T17:41:10.986584Z",
    app_metadata: { provider: "email", providers: [ "email" ] },
    user_metadata: { email_verified: true },
    identities: [
      {
        identity_id: "b2f3094d-a29b-42b5-be69-3397282ffcd7",
        id: "95d1f381-7023-4f33-bc54-08ccd08abf41",
        user_id: "95d1f381-7023-4f33-bc54-08ccd08abf41",
        identity_data: {
          email: "guillermo.arrieta@lasalle.mx",
          email_verified: false,
          phone_verified: false,
          sub: "95d1f381-7023-4f33-bc54-08ccd08abf41"
        },
        provider: "email",
        last_sign_in_at: "2026-01-13T14:54:39.085382Z",
        created_at: "2026-01-13T14:54:39.08544Z",
        updated_at: "2026-01-13T14:54:39.08544Z",
        email: "guillermo.arrieta@lasalle.mx"
      }
    ],
    created_at: "2026-01-13T14:54:39.081453Z",
    updated_at: "2026-03-02T18:39:41.80176Z",
    is_anonymous: false
  }
}
TOKEN_REFRESHED {
  aal: "aal1",
  amr: [ { method: "password", timestamp: 1772473271 } ],
  app_metadata: { provider: "email", providers: [ "email" ] },
  aud: "authenticated",
  email: "guillermo.arrieta@lasalle.mx",
  exp: 1772483893,
  feature_x: true,
  iat: 1772480293,
  is_anonymous: false,
  iss: "http://127.0.0.1:54321/auth/v1",
  phone: "",
  role: "authenticated",
  session_id: "f76f4ddf-e719-464b-b0ae-80a6b120efa4",
  sub: "95d1f381-7023-4f33-bc54-08ccd08abf41",
  tenant_id: "local-dev-tenant",
  user_metadata: { email_verified: true }
}
{
  access_token: "eyJhbGciOiJFUzI1NiIsImtpZCI6ImI4MTI2OWYxLTIxZDgtNGYyZS1iNzE5LWMyMjQwYTg0MGQ5MCIsInR5cCI6IkpXVCJ9.eyJhYWwiOiJhYWwxIiwiYW1yIjpbeyJtZXRob2QiOiJwYXNzd29yZCIsInRpbWVzdGFtcCI6MTc3MjQ3MzI3MX1dLCJhcHBfbWV0YWRhdGEiOnsicHJvdmlkZXIiOiJlbWFpbCIsInByb3ZpZGVycyI6WyJlbWFpbCJdfSwiYXVkIjoiYXV0aGVudGljYXRlZCIsImVtYWlsIjoiZ3VpbGxlcm1vLmFycmlldGFAbGFzYWxsZS5teCIsImV4cCI6MTc3MjQ4Mzg5MywiZmVhdHVyZV94Ijp0cnVlLCJpYXQiOjE3NzI0ODAyOTMsImlzX2Fub255bW91cyI6ZmFsc2UsImlzcyI6Imh0dHA6Ly8xMjcuMC4wLjE6NTQzMjEvYXV0aC92MSIsInBob25lIjoiIiwicm9sZSI6ImF1dGhlbnRpY2F0ZWQiLCJzZXNzaW9uX2lkIjoiZjc2ZjRkZGYtZTcxOS00NjRiLWIwYWUtODBhNmIxMjBlZmE0Iiwic3ViIjoiOTVkMWYzODEtNzAyMy00ZjMzLWJjNTQtMDhjY2QwOGFiZjQxIiwidGVuYW50X2lkIjoibG9jYWwtZGV2LXRlbmFudCIsInVzZXJfbWV0YWRhdGEiOnsiZW1haWxfdmVyaWZpZWQiOnRydWV9fQ.TUYrfJrHy3fwPwI4VD24oYunaNAehDMnJleKn_JQg5LHwBIqe422qlGkNXvhu7juknS-kcEjJ1MaXBAP4Cu_WQ",
  token_type: "bearer",
  expires_in: 3600,
  expires_at: 1772483893,
  refresh_token: "s35spp4fy6oe",
  user: {
    id: "95d1f381-7023-4f33-bc54-08ccd08abf41",
    aud: "authenticated",
    role: "authenticated",
    email: "guillermo.arrieta@lasalle.mx",
    email_confirmed_at: "2026-01-13T14:54:39.096101Z",
    phone: "",
    confirmed_at: "2026-01-13T14:54:39.096101Z",
    last_sign_in_at: "2026-03-02T17:41:10.986584Z",
    app_metadata: { provider: "email", providers: [ "email" ] },
    user_metadata: { email_verified: true },
    identities: [
      {
        identity_id: "b2f3094d-a29b-42b5-be69-3397282ffcd7",
        id: "95d1f381-7023-4f33-bc54-08ccd08abf41",
        user_id: "95d1f381-7023-4f33-bc54-08ccd08abf41",
        identity_data: {
          email: "guillermo.arrieta@lasalle.mx",
          email_verified: false,
          phone_verified: false,
          sub: "95d1f381-7023-4f33-bc54-08ccd08abf41"
        },
        provider: "email",
        last_sign_in_at: "2026-01-13T14:54:39.085382Z",
        created_at: "2026-01-13T14:54:39.08544Z",
        updated_at: "2026-01-13T14:54:39.08544Z",
        email: "guillermo.arrieta@lasalle.mx"
      }
    ],
    created_at: "2026-01-13T14:54:39.081453Z",
    updated_at: "2026-03-02T19:38:13.130638Z",
    is_anonymous: false
  }
}
const raw = localStorage.getItem("jwt")
const jwt = raw ? JSON.parse(raw) : null

console.log(jwt)
{
  access_token: "eyJhbGciOiJFUzI1NiIsImtpZCI6ImI4MTI2OWYxLTIxZDgtNGYyZS1iNzE5LWMyMjQwYTg0MGQ5MCIsInR5cCI6IkpXVCJ9.eyJhYWwiOiJhYWwxIiwiYW1yIjpbeyJtZXRob2QiOiJwYXNzd29yZCIsInRpbWVzdGFtcCI6MTc3MjQ1OTQzMX1dLCJhcHBfbWV0YWRhdGEiOnsicHJvdmlkZXIiOiJlbWFpbCIsInByb3ZpZGVycyI6WyJlbWFpbCJdfSwiYXVkIjoiYXV0aGVudGljYXRlZCIsImVtYWlsIjoiZ3VpbGxlcm1vLmFycmlldGFAbGFzYWxsZS5teCIsImV4cCI6MTc3MjQ3MjAwMywiZmVhdHVyZV94Ijp0cnVlLCJpYXQiOjE3NzI0Njg0MDMsImlzX2Fub255bW91cyI6ZmFsc2UsImlzcyI6Imh0dHA6Ly8xMjcuMC4wLjE6NTQzMjEvYXV0aC92MSIsInBob25lIjoiIiwicm9sZSI6ImF1dGhlbnRpY2F0ZWQiLCJzZXNzaW9uX2lkIjoiMTJkNDc0OGUtNDBiMy00MzQ5LWI0MjUtMWFkNzM2YTk2NTM5Iiwic3ViIjoiOTVkMWYzODEtNzAyMy00ZjMzLWJjNTQtMDhjY2QwOGFiZjQxIiwidGVuYW50X2lkIjoibG9jYWwtZGV2LXRlbmFudCIsInVzZXJfbWV0YWRhdGEiOnsiZW1haWxfdmVyaWZpZWQiOnRydWV9fQ.XbxmaKPEo9Vqr1_W1vuXIaYwGiifaBsaqIwFdJvIuMrFPx5VeW9-NeUasWq3ka1DBsEMWaCFeIKykp9QlvDXqQ",
  token_type: "bearer",
  expires_in: 3600,
  expires_at: 1772472003,
  refresh_token: "gjdfzz4y4y3v",
  user: {
    id: "95d1f381-7023-4f33-bc54-08ccd08abf41",
    aud: "authenticated",
    role: "authenticated",
    email: "guillermo.arrieta@lasalle.mx",
    email_confirmed_at: "2026-01-13T14:54:39.096101Z",
    phone: "",
    confirmed_at: "2026-01-13T14:54:39.096101Z",
    last_sign_in_at: "2026-03-02T13:50:31.464916Z",
    app_metadata: { provider: "email", providers: [ "email" ] },
    user_metadata: { email_verified: true },
    identities: [
      {
        identity_id: "b2f3094d-a29b-42b5-be69-3397282ffcd7",
        id: "95d1f381-7023-4f33-bc54-08ccd08abf41",
        user_id: "95d1f381-7023-4f33-bc54-08ccd08abf41",
        identity_data: {
          email: "guillermo.arrieta@lasalle.mx",
          email_verified: false,
          phone_verified: false,
          sub: "95d1f381-7023-4f33-bc54-08ccd08abf41"
        },
        provider: "email",
        last_sign_in_at: "2026-01-13T14:54:39.085382Z",
        created_at: "2026-01-13T14:54:39.08544Z",
        updated_at: "2026-01-13T14:54:39.08544Z",
        email: "guillermo.arrieta@lasalle.mx"
      }
    ],
    created_at: "2026-01-13T14:54:39.081453Z",
    updated_at: "2026-03-02T16:20:03.535209Z",
    is_anonymous: false
  }
}
useEffect(() => {
  const onFocus = () => supabase.auth.refreshSession();
  window.addEventListener("focus", onFocus);
  return () => window.removeEventListener("focus", onFocus);
}, []);
Stack trace:
ReferenceError: useEffect is not defined
    at <anonymous>:1:22