1+ import { assert } from 'console'
12import { createClient , RealtimeChannel , SupabaseClient } from '../src/index'
2-
3+ import { sign } from 'jsonwebtoken'
34// These tests assume that a local Supabase server is already running
45// Start a local Supabase instance with 'supabase start' before running these tests
56// Default local dev credentials from Supabase CLI
67const SUPABASE_URL = 'http://127.0.0.1:54321'
78const ANON_KEY =
89 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0'
9-
10+ const JWT_SECRET = 'super-secret-jwt-token-with-at-least-32-characters-long'
1011// For Node.js < 22, we need to provide a WebSocket implementation
1112// Node.js 22+ has native WebSocket support
1213let wsTransport : any = undefined
@@ -292,7 +293,7 @@ describe('Supabase Integration Tests', () => {
292293
293294 channel
294295 . on ( 'broadcast' , { event : '*' } , ( payload ) => ( receivedMessage = payload ) )
295- . subscribe ( ( status ) => {
296+ . subscribe ( ( status , err ) => {
296297 if ( status == 'SUBSCRIBED' ) subscribed = true
297298 } )
298299
@@ -316,52 +317,6 @@ describe('Supabase Integration Tests', () => {
316317 expect ( receivedMessage ) . toBeDefined ( )
317318 expect ( supabase . realtime . getChannels ( ) . length ) . toBe ( 1 )
318319 } , 10000 )
319-
320- test ( 'should automatically set auth token when using custom JWT without manual setAuth()' , async ( ) => {
321- // Sign up a user with the normal client to get a real JWT token
322- await supabase . auth . signOut ( )
323- const email = `custom-jwt-${ Date . now ( ) } @example.com`
324- const password = 'password123'
325- const { data : signUpData } = await supabase . auth . signUp ( { email, password } )
326- expect ( signUpData . session ) . toBeDefined ( )
327- const realJwtToken = signUpData . session ! . access_token
328-
329- const customJwtClient = createClient ( SUPABASE_URL , ANON_KEY , {
330- accessToken : async ( ) => realJwtToken ,
331- realtime : {
332- heartbeatIntervalMs : 500 ,
333- ...( wsTransport && { transport : wsTransport } ) ,
334- } ,
335- } )
336-
337- await new Promise ( ( resolve ) => setTimeout ( resolve , 100 ) )
338-
339- expect ( ( customJwtClient . realtime as any ) . accessTokenValue ) . toBe ( realJwtToken )
340-
341- const customChannelName = `custom-jwt-channel-${ crypto . randomUUID ( ) } `
342- const config = { broadcast : { self : true } , private : true }
343- const customChannel = customJwtClient . channel ( customChannelName , { config } )
344-
345- expect ( ( customChannel as any ) . joinPush . payload . access_token ) . toBe ( realJwtToken )
346-
347- let subscribed = false
348- let attempts = 0
349-
350- customChannel . subscribe ( ( status ) => {
351- if ( status == 'SUBSCRIBED' ) subscribed = true
352- } )
353-
354- while ( ! subscribed ) {
355- if ( attempts > 50 ) throw new Error ( 'Timeout waiting for subscription' )
356- await new Promise ( ( resolve ) => setTimeout ( resolve , 100 ) )
357- attempts ++
358- }
359-
360- expect ( subscribed ) . toBe ( true )
361- expect ( customJwtClient . realtime . getChannels ( ) . length ) . toBe ( 1 )
362-
363- await customJwtClient . removeAllChannels ( )
364- } , 10000 )
365320 } )
366321} )
367322
@@ -404,3 +359,31 @@ describe('Storage API', () => {
404359 expect ( deleteError ) . toBeNull ( )
405360 } )
406361} )
362+
363+ describe ( 'Custom JWT' , ( ) => {
364+ describe ( 'Realtime' , ( ) => {
365+ test ( 'will connect with a properly signed jwt token' , async ( ) => {
366+ const jwtToken = sign ( { sub : '1234567890' } , JWT_SECRET , { expiresIn : '1h' } )
367+ const supabaseWithCustomJwt = createClient ( SUPABASE_URL , ANON_KEY , {
368+ accessToken : ( ) => Promise . resolve ( jwtToken ) ,
369+ } )
370+ await new Promise ( ( resolve ) => setTimeout ( resolve , 100 ) )
371+ expect ( supabaseWithCustomJwt . realtime . accessTokenValue ) . toBe ( jwtToken )
372+ let subscribed = false
373+ let attempts = 0
374+ supabaseWithCustomJwt . channel ( 'test-channel' ) . subscribe ( ( status ) => {
375+ if ( status == 'SUBSCRIBED' ) subscribed = true
376+ } )
377+
378+ // Wait for subscription
379+ while ( ! subscribed ) {
380+ if ( attempts > 50 ) throw new Error ( 'Timeout waiting for subscription' )
381+ await new Promise ( ( resolve ) => setTimeout ( resolve , 100 ) )
382+ attempts ++
383+ }
384+
385+ expect ( subscribed ) . toBe ( true )
386+ //
387+ } , 10000 )
388+ } )
389+ } )
0 commit comments