Skip to content

Commit 9f99a81

Browse files
committed
feat: push access token to every channel during heartbeat
1 parent fb88b24 commit 9f99a81

File tree

3 files changed

+45
-6
lines changed

3 files changed

+45
-6
lines changed

packages/core/realtime-js/src/RealtimeClient.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ type Message = {
3434
const noop = () => {}
3535

3636
export default class RealtimeClient {
37+
accessToken: string | null = null
3738
channels: RealtimeSubscription[] = []
3839
endPoint: string = ''
3940
headers?: { [key: string]: string } = DEFAULT_HEADERS
@@ -317,6 +318,21 @@ export default class RealtimeClient {
317318
return this.ref.toString()
318319
}
319320

321+
/**
322+
* Sets the JWT access token used for channel subscription authorization and Realtime RLS.
323+
*
324+
* @param token A JWT string.
325+
*/
326+
setAuth(token: string | null) {
327+
this.accessToken = token
328+
329+
this.channels.forEach((channel) =>
330+
channel.push(CHANNEL_EVENTS.access_token, {
331+
access_token: token,
332+
})
333+
)
334+
}
335+
320336
private _onConnOpen() {
321337
this.log('transport', `connected to ${this.endPointURL()}`)
322338
this._flushSendBuffer()
@@ -385,11 +401,6 @@ export default class RealtimeClient {
385401
return
386402
}
387403
this.pendingHeartbeatRef = this.makeRef()
388-
this.push({
389-
topic: 'phoenix',
390-
event: 'heartbeat',
391-
payload: {},
392-
ref: this.pendingHeartbeatRef,
393-
})
404+
this.setAuth(this.accessToken)
394405
}
395406
}

packages/core/realtime-js/src/lib/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export enum CHANNEL_EVENTS {
2929
join = 'phx_join',
3030
reply = 'phx_reply',
3131
leave = 'phx_leave',
32+
access_token = 'access_token',
3233
}
3334

3435
export enum TRANSPORTS {

packages/core/realtime-js/test/socket_test.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,33 @@ describe('makeRef', () => {
444444
})
445445
})
446446

447+
describe('setAuth', () => {
448+
beforeEach(() => {
449+
socket = new RealtimeClient('wss://example.com/socket')
450+
})
451+
452+
afterEach(async () => {
453+
await socket.disconnect()
454+
})
455+
456+
it('sets access token and pushes it to channels', () => {
457+
const channel1 = socket.channel('test-topic1')
458+
const channel2 = socket.channel('test-topic2')
459+
const stub1 = sinon.stub(channel1, 'push')
460+
const stub2 = sinon.stub(channel2, 'push')
461+
462+
socket.setAuth('token123')
463+
464+
assert.strictEqual(socket.accessToken, 'token123')
465+
assert.ok(stub1.calledWith('access_token', {
466+
access_token: 'token123',
467+
}))
468+
assert.ok(stub2.calledWith('access_token', {
469+
access_token: 'token123',
470+
}))
471+
})
472+
})
473+
447474
describe('sendHeartbeat', () => {
448475
before(() => {
449476
window.XMLHttpRequest = sinon.useFakeXMLHttpRequest()

0 commit comments

Comments
 (0)