feat: add jwt-decode dependency and implement JWT handling in Supabase security notebook
This commit is contained in:
@@ -23,6 +23,7 @@
|
|||||||
"npm:@toon-format/toon@^2.1.0": "2.1.0",
|
"npm:@toon-format/toon@^2.1.0": "2.1.0",
|
||||||
"npm:@types/bun@^1.3.5": "1.3.5",
|
"npm:@types/bun@^1.3.5": "1.3.5",
|
||||||
"npm:deno@^2.6.4": "2.6.4",
|
"npm:deno@^2.6.4": "2.6.4",
|
||||||
|
"npm:jwt-decode@4": "4.0.0",
|
||||||
"npm:openai@6.16.0": "6.16.0_zod@3.25.76",
|
"npm:openai@6.16.0": "6.16.0_zod@3.25.76",
|
||||||
"npm:openai@^4.52.5": "4.104.0_zod@3.25.76",
|
"npm:openai@^4.52.5": "4.104.0_zod@3.25.76",
|
||||||
"npm:openai@^6.16.0": "6.16.0_zod@3.25.76",
|
"npm:openai@^6.16.0": "6.16.0_zod@3.25.76",
|
||||||
@@ -419,6 +420,9 @@
|
|||||||
"imurmurhash@0.1.4": {
|
"imurmurhash@0.1.4": {
|
||||||
"integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="
|
"integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="
|
||||||
},
|
},
|
||||||
|
"jwt-decode@4.0.0": {
|
||||||
|
"integrity": "sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA=="
|
||||||
|
},
|
||||||
"math-intrinsics@1.1.0": {
|
"math-intrinsics@1.1.0": {
|
||||||
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="
|
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="
|
||||||
},
|
},
|
||||||
@@ -593,6 +597,7 @@
|
|||||||
"npm:@toon-format/toon@^2.1.0",
|
"npm:@toon-format/toon@^2.1.0",
|
||||||
"npm:@types/bun@^1.3.5",
|
"npm:@types/bun@^1.3.5",
|
||||||
"npm:deno@^2.6.4",
|
"npm:deno@^2.6.4",
|
||||||
|
"npm:jwt-decode@4",
|
||||||
"npm:openai@^6.16.0",
|
"npm:openai@^6.16.0",
|
||||||
"npm:supabase@^2.72.6"
|
"npm:supabase@^2.72.6"
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -0,0 +1,223 @@
|
|||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 1,
|
||||||
|
"id": "3b0acbc3",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import { createClient } from \"@supabase/supabase-js\";\n",
|
||||||
|
"const supabaseUrl = Deno.env.get(\"SUPABASE_URL\") || env.SUPABASE_URL;\n",
|
||||||
|
"const supabaseKey = Deno.env.get(\"SUPABASE_ANON_KEY\") || env.SUPABASE_ANON_KEY;\n",
|
||||||
|
"\n",
|
||||||
|
"const supabase = createClient(supabaseUrl, supabaseKey);\n",
|
||||||
|
"const supa = await supabase.auth.signInWithPassword({\n",
|
||||||
|
" email: 'guillermo.arrieta@lasalle.mx',\n",
|
||||||
|
" password: 'admin',\n",
|
||||||
|
"});"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "6ef7e79f",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"{\n",
|
||||||
|
" access_token: \"eyJhbGciOiJFUzI1NiIsImtpZCI6ImI4MTI2OWYxLTIxZDgtNGYyZS1iNzE5LWMyMjQwYTg0MGQ5MCIsInR5cCI6IkpXVCJ9.eyJhYWwiOiJhYWwxIiwiYW1yIjpbeyJtZXRob2QiOiJwYXNzd29yZCIsInRpbWVzdGFtcCI6MTc3MjQ3MzI3MX1dLCJhcHBfbWV0YWRhdGEiOnsicHJvdmlkZXIiOiJlbWFpbCIsInByb3ZpZGVycyI6WyJlbWFpbCJdfSwiYXVkIjoiYXV0aGVudGljYXRlZCIsImVtYWlsIjoiZ3VpbGxlcm1vLmFycmlldGFAbGFzYWxsZS5teCIsImV4cCI6MTc3MjQ3Njg3MSwiZmVhdHVyZV94Ijp0cnVlLCJpYXQiOjE3NzI0NzMyNzEsImlzX2Fub255bW91cyI6ZmFsc2UsImlzcyI6Imh0dHA6Ly8xMjcuMC4wLjE6NTQzMjEvYXV0aC92MSIsInBob25lIjoiIiwicm9sZSI6ImF1dGhlbnRpY2F0ZWQiLCJzZXNzaW9uX2lkIjoiZjc2ZjRkZGYtZTcxOS00NjRiLWIwYWUtODBhNmIxMjBlZmE0Iiwic3ViIjoiOTVkMWYzODEtNzAyMy00ZjMzLWJjNTQtMDhjY2QwOGFiZjQxIiwidGVuYW50X2lkIjoibG9jYWwtZGV2LXRlbmFudCIsInVzZXJfbWV0YWRhdGEiOnsiZW1haWxfdmVyaWZpZWQiOnRydWV9fQ.LEXrbBNetdCb8zfCiLcXhJg3EmX6XuE4cYOaFmYg1PhvvNI5XorbJQHhb4SQVggQDOauIqqkMRsK64GK1nheIw\",\n",
|
||||||
|
" token_type: \"bearer\",\n",
|
||||||
|
" expires_in: 3600,\n",
|
||||||
|
" expires_at: 1772476871,\n",
|
||||||
|
" refresh_token: \"lwgtrzw2tpzl\",\n",
|
||||||
|
" user: {\n",
|
||||||
|
" id: \"95d1f381-7023-4f33-bc54-08ccd08abf41\",\n",
|
||||||
|
" aud: \"authenticated\",\n",
|
||||||
|
" role: \"authenticated\",\n",
|
||||||
|
" email: \"guillermo.arrieta@lasalle.mx\",\n",
|
||||||
|
" email_confirmed_at: \"2026-01-13T14:54:39.096101Z\",\n",
|
||||||
|
" phone: \"\",\n",
|
||||||
|
" confirmed_at: \"2026-01-13T14:54:39.096101Z\",\n",
|
||||||
|
" last_sign_in_at: \"2026-03-02T17:41:10.98658403Z\",\n",
|
||||||
|
" app_metadata: { provider: \"email\", providers: [ \"email\" ] },\n",
|
||||||
|
" user_metadata: { email_verified: true },\n",
|
||||||
|
" identities: [\n",
|
||||||
|
" {\n",
|
||||||
|
" identity_id: \"b2f3094d-a29b-42b5-be69-3397282ffcd7\",\n",
|
||||||
|
" id: \"95d1f381-7023-4f33-bc54-08ccd08abf41\",\n",
|
||||||
|
" user_id: \"95d1f381-7023-4f33-bc54-08ccd08abf41\",\n",
|
||||||
|
" identity_data: {\n",
|
||||||
|
" email: \"guillermo.arrieta@lasalle.mx\",\n",
|
||||||
|
" email_verified: false,\n",
|
||||||
|
" phone_verified: false,\n",
|
||||||
|
" sub: \"95d1f381-7023-4f33-bc54-08ccd08abf41\"\n",
|
||||||
|
" },\n",
|
||||||
|
" provider: \"email\",\n",
|
||||||
|
" last_sign_in_at: \"2026-01-13T14:54:39.085382Z\",\n",
|
||||||
|
" created_at: \"2026-01-13T14:54:39.08544Z\",\n",
|
||||||
|
" updated_at: \"2026-01-13T14:54:39.08544Z\",\n",
|
||||||
|
" email: \"guillermo.arrieta@lasalle.mx\"\n",
|
||||||
|
" }\n",
|
||||||
|
" ],\n",
|
||||||
|
" created_at: \"2026-01-13T14:54:39.081453Z\",\n",
|
||||||
|
" updated_at: \"2026-03-02T17:41:11.002577Z\",\n",
|
||||||
|
" is_anonymous: false\n",
|
||||||
|
" },\n",
|
||||||
|
" weak_password: {\n",
|
||||||
|
" message: \"Password should be at least 6 characters.\",\n",
|
||||||
|
" reasons: [ \"length\" ]\n",
|
||||||
|
" }\n",
|
||||||
|
"}\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"text/plain": [
|
||||||
|
"{\n",
|
||||||
|
" data: {\n",
|
||||||
|
" subscription: {\n",
|
||||||
|
" id: \u001b[32mSymbol(\"auth-callback\")\u001b[39m,\n",
|
||||||
|
" callback: \u001b[36m[AsyncFunction (anonymous)]\u001b[39m,\n",
|
||||||
|
" unsubscribe: \u001b[36m[Function: unsubscribe]\u001b[39m\n",
|
||||||
|
" }\n",
|
||||||
|
" }\n",
|
||||||
|
"}"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"execution_count": 3,
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "execute_result"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"import { jwtDecode } from \"npm:jwt-decode\";\n",
|
||||||
|
"\n",
|
||||||
|
"const listener = supabase.auth.onAuthStateChange(async (event, session) => {\n",
|
||||||
|
" if (session) {\n",
|
||||||
|
" const jwt = jwtDecode(session.access_token);\n",
|
||||||
|
" console.log(event, jwt);\n",
|
||||||
|
" // store in the session\n",
|
||||||
|
" localStorage.setItem(\"jwt\", JSON.stringify(session));\n",
|
||||||
|
" }\n",
|
||||||
|
"});\n",
|
||||||
|
"\n",
|
||||||
|
"listener;\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 35,
|
||||||
|
"id": "0471a2d4",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"{\n",
|
||||||
|
" access_token: \"eyJhbGciOiJFUzI1NiIsImtpZCI6ImI4MTI2OWYxLTIxZDgtNGYyZS1iNzE5LWMyMjQwYTg0MGQ5MCIsInR5cCI6IkpXVCJ9.eyJhYWwiOiJhYWwxIiwiYW1yIjpbeyJtZXRob2QiOiJwYXNzd29yZCIsInRpbWVzdGFtcCI6MTc3MjQ1OTQzMX1dLCJhcHBfbWV0YWRhdGEiOnsicHJvdmlkZXIiOiJlbWFpbCIsInByb3ZpZGVycyI6WyJlbWFpbCJdfSwiYXVkIjoiYXV0aGVudGljYXRlZCIsImVtYWlsIjoiZ3VpbGxlcm1vLmFycmlldGFAbGFzYWxsZS5teCIsImV4cCI6MTc3MjQ3MjAwMywiZmVhdHVyZV94Ijp0cnVlLCJpYXQiOjE3NzI0Njg0MDMsImlzX2Fub255bW91cyI6ZmFsc2UsImlzcyI6Imh0dHA6Ly8xMjcuMC4wLjE6NTQzMjEvYXV0aC92MSIsInBob25lIjoiIiwicm9sZSI6ImF1dGhlbnRpY2F0ZWQiLCJzZXNzaW9uX2lkIjoiMTJkNDc0OGUtNDBiMy00MzQ5LWI0MjUtMWFkNzM2YTk2NTM5Iiwic3ViIjoiOTVkMWYzODEtNzAyMy00ZjMzLWJjNTQtMDhjY2QwOGFiZjQxIiwidGVuYW50X2lkIjoibG9jYWwtZGV2LXRlbmFudCIsInVzZXJfbWV0YWRhdGEiOnsiZW1haWxfdmVyaWZpZWQiOnRydWV9fQ.XbxmaKPEo9Vqr1_W1vuXIaYwGiifaBsaqIwFdJvIuMrFPx5VeW9-NeUasWq3ka1DBsEMWaCFeIKykp9QlvDXqQ\",\n",
|
||||||
|
" token_type: \"bearer\",\n",
|
||||||
|
" expires_in: 3600,\n",
|
||||||
|
" expires_at: 1772472003,\n",
|
||||||
|
" refresh_token: \"gjdfzz4y4y3v\",\n",
|
||||||
|
" user: {\n",
|
||||||
|
" id: \"95d1f381-7023-4f33-bc54-08ccd08abf41\",\n",
|
||||||
|
" aud: \"authenticated\",\n",
|
||||||
|
" role: \"authenticated\",\n",
|
||||||
|
" email: \"guillermo.arrieta@lasalle.mx\",\n",
|
||||||
|
" email_confirmed_at: \"2026-01-13T14:54:39.096101Z\",\n",
|
||||||
|
" phone: \"\",\n",
|
||||||
|
" confirmed_at: \"2026-01-13T14:54:39.096101Z\",\n",
|
||||||
|
" last_sign_in_at: \"2026-03-02T13:50:31.464916Z\",\n",
|
||||||
|
" app_metadata: { provider: \"email\", providers: [ \"email\" ] },\n",
|
||||||
|
" user_metadata: { email_verified: true },\n",
|
||||||
|
" identities: [\n",
|
||||||
|
" {\n",
|
||||||
|
" identity_id: \"b2f3094d-a29b-42b5-be69-3397282ffcd7\",\n",
|
||||||
|
" id: \"95d1f381-7023-4f33-bc54-08ccd08abf41\",\n",
|
||||||
|
" user_id: \"95d1f381-7023-4f33-bc54-08ccd08abf41\",\n",
|
||||||
|
" identity_data: {\n",
|
||||||
|
" email: \"guillermo.arrieta@lasalle.mx\",\n",
|
||||||
|
" email_verified: false,\n",
|
||||||
|
" phone_verified: false,\n",
|
||||||
|
" sub: \"95d1f381-7023-4f33-bc54-08ccd08abf41\"\n",
|
||||||
|
" },\n",
|
||||||
|
" provider: \"email\",\n",
|
||||||
|
" last_sign_in_at: \"2026-01-13T14:54:39.085382Z\",\n",
|
||||||
|
" created_at: \"2026-01-13T14:54:39.08544Z\",\n",
|
||||||
|
" updated_at: \"2026-01-13T14:54:39.08544Z\",\n",
|
||||||
|
" email: \"guillermo.arrieta@lasalle.mx\"\n",
|
||||||
|
" }\n",
|
||||||
|
" ],\n",
|
||||||
|
" created_at: \"2026-01-13T14:54:39.081453Z\",\n",
|
||||||
|
" updated_at: \"2026-03-02T16:20:03.535209Z\",\n",
|
||||||
|
" is_anonymous: false\n",
|
||||||
|
" }\n",
|
||||||
|
"}\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"const raw = localStorage.getItem(\"jwt\")\n",
|
||||||
|
"const jwt = raw ? JSON.parse(raw) : null\n",
|
||||||
|
"\n",
|
||||||
|
"console.log(jwt)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 36,
|
||||||
|
"id": "0bfcd412",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"ename": "ReferenceError",
|
||||||
|
"evalue": "useEffect is not defined",
|
||||||
|
"output_type": "error",
|
||||||
|
"traceback": [
|
||||||
|
"Stack trace:",
|
||||||
|
"ReferenceError: useEffect is not defined",
|
||||||
|
" at <anonymous>:1:22"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"useEffect(() => {\n",
|
||||||
|
" const onFocus = () => supabase.auth.refreshSession();\n",
|
||||||
|
" window.addEventListener(\"focus\", onFocus);\n",
|
||||||
|
" return () => window.removeEventListener(\"focus\", onFocus);\n",
|
||||||
|
"}, []);"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "88d2d6bc",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Deno",
|
||||||
|
"language": "typescript",
|
||||||
|
"name": "deno"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": "typescript",
|
||||||
|
"file_extension": ".ts",
|
||||||
|
"mimetype": "text/x.typescript",
|
||||||
|
"name": "typescript",
|
||||||
|
"nbconvert_exporter": "script",
|
||||||
|
"pygments_lexer": "typescript",
|
||||||
|
"version": "5.9.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 5
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
"@supabase/supabase-js": "^2.90.1",
|
"@supabase/supabase-js": "^2.90.1",
|
||||||
"@toon-format/toon": "^2.1.0",
|
"@toon-format/toon": "^2.1.0",
|
||||||
"deno": "^2.6.4",
|
"deno": "^2.6.4",
|
||||||
|
"jwt-decode": "^4.0.0",
|
||||||
"openai": "^6.16.0",
|
"openai": "^6.16.0",
|
||||||
"supabase": "^2.72.6"
|
"supabase": "^2.72.6"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
v2.185.0
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
postgresql://postgres.exdkssurzmjnnhgtiama@aws-0-us-west-1.pooler.supabase.com:5432/postgres
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
15.8.1.085
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
exdkssurzmjnnhgtiama
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
v12.2.3
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
buckets-objects-grants-postgres
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
v1.33.0
|
|
||||||
@@ -48,3 +48,7 @@ entrypoint = "./functions/generate-subject-suggestions/index.ts"
|
|||||||
# Specifies static files to be bundled with the function. Supports glob patterns.
|
# Specifies static files to be bundled with the function. Supports glob patterns.
|
||||||
# For example, if you want to serve static HTML pages in your function:
|
# For example, if you want to serve static HTML pages in your function:
|
||||||
# static_files = [ "./functions/generate-subject-suggestions/*.html" ]
|
# static_files = [ "./functions/generate-subject-suggestions/*.html" ]
|
||||||
|
|
||||||
|
[auth.hook.custom_access_token]
|
||||||
|
enabled = true
|
||||||
|
uri = "pg-functions://postgres/public/custom_access_token_hook"
|
||||||
Reference in New Issue
Block a user