Skip to content

Commit

Permalink
Implement SAT refresh on expiration for CF (#825)
Browse files Browse the repository at this point in the history
* Implement SAT refresh on expiration

* changeset include

* promisify refereshToken function
  • Loading branch information
iAmmar7 committed Jul 18, 2023
1 parent a742673 commit b44bd6f
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 5 deletions.
6 changes: 6 additions & 0 deletions .changeset/green-wolves-lick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@signalwire/core': patch
'@signalwire/js': patch
---

Added support for user-defined refresh token function to update SAT
4 changes: 4 additions & 0 deletions internal/playground-js/src/fabric-callee/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ async function getClient() {
host: document.getElementById('host').value,
token: document.getElementById('token').value,
rootElement: document.getElementById('rootElement'),
onRefreshToken: async () => {
// Fetch the new token and update the client using 👇
// await client.updateToken(newToken)
},
})
}

Expand Down
14 changes: 10 additions & 4 deletions packages/core/src/BaseJWTSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export class BaseJWTSession extends BaseSession {
try {
this._rpcConnectResult = await this.execute(RPCConnect(params))
await this.persistRelayProtocol()
this._checkTokenExpiration()
await this._checkTokenExpiration()
} catch (error) {
this.logger.debug('BaseJWTSession authenticate error', error)
throw error
Expand Down Expand Up @@ -147,15 +147,21 @@ export class BaseJWTSession extends BaseSession {
* Set a timer to dispatch a notification when the JWT is going to expire.
* @return void
*/
protected _checkTokenExpiration() {
protected async _checkTokenExpiration() {
if (!this.expiresAt) {
return
}
const refreshTokenFn =
this.options._onRefreshToken || this.options.onRefreshToken
if (this.expiresIn <= this._refreshTokenNotificationDiff) {
this.dispatch(authExpiringAction())

if (this.options._onRefreshToken) {
this.options._onRefreshToken()
if (typeof refreshTokenFn === 'function') {
try {
await refreshTokenFn()
} catch (error) {
this.logger.error(error)
}
} else {
this.logger.warn('The token is going to expire!')
}
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/utils/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,15 @@ export interface SessionOptions {
// From `LogLevelDesc` of loglevel to simplify our docs
/** logging level */
logLevel?: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'silent'
/** To refresh the auth token */
onRefreshToken?(): Promise<void>
/**
* The SDK invokes this method and uses the new token to re-auth.
* TODO: rename it: getNewToken, getRefreshedToken, fetchToken (?)
*
* @internal
* */
_onRefreshToken?(): void
_onRefreshToken?(): Promise<void>
sessionChannel?: SessionChannel
}
export interface UserOptions extends SessionOptions {
Expand Down
2 changes: 2 additions & 0 deletions packages/js/src/fabric/SignalWire.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ interface SignalWireContract {
disconnect: WSClient['disconnect']
dial: WSClient['dial']
handlePushNotification: WSClient['handlePushNotification']
updateToken: WSClient['updateToken']
}

export const SignalWire = (
Expand All @@ -34,6 +35,7 @@ export const SignalWire = (
disconnect: wsClient.disconnect.bind(wsClient),
dial: wsClient.dial.bind(wsClient),
handlePushNotification: wsClient.handlePushNotification.bind(wsClient),
updateToken: wsClient.updateToken.bind(wsClient),
// @ts-expect-error
__httpClient: httpClient,
__wsClient: wsClient,
Expand Down
15 changes: 15 additions & 0 deletions packages/js/src/fabric/WSClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,4 +244,19 @@ export class WSClient {
throw error
}
}

updateToken(token: string): Promise<void> {
return new Promise((resolve, reject) => {
// @ts-expect-error
this.wsClient.once('session.auth_error', (error) => {
reject(error)
})
this.wsClient.once('session.connected', () => {
resolve()
})

// @ts-expect-error
this.wsClient.reauthenticate(token)
})
}
}

0 comments on commit b44bd6f

Please sign in to comment.