Skip to content

Commit

Permalink
v7.0.0 - socket.authState can no longer be in a 'pending' state.
Browse files Browse the repository at this point in the history
The 'pending' authState used to represent the ambiguous authentication state which might occur when the
socket is disconnected (for whatever reason). It was removed because it was too ambiguous to be useful.
Instead, socket.authState now reports the last known authentication status (optimistic approach).
Once a socket is authenticated with a valid JWT, the socket will now report itself as being 'authenticated'
until the server explicitly indicates otherwise (e.g. the server invalidated the token).
  • Loading branch information
jondubois committed Aug 13, 2017
1 parent 1403093 commit 01a6677
Show file tree
Hide file tree
Showing 7 changed files with 238 additions and 63 deletions.
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "socketcluster-client",
"main": "socketcluster.js",
"version": "6.5.0",
"version": "7.0.0",
"homepage": "https://github.com/SocketCluster/socketcluster-client",
"description": "SocketCluster JavaScript client",
"authors": [
Expand Down
2 changes: 1 addition & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ module.exports.destroy = function (options) {

module.exports.connections = SCSocketCreator.connections;

module.exports.version = '6.5.0';
module.exports.version = '7.0.0';
3 changes: 3 additions & 0 deletions lib/scsocket.js
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,9 @@ SCSocket.prototype._onSCOpen = function (status) {
this._changeToUnauthenticatedStateAndClearTokens();
}
} else {
// This can happen if auth.loadToken (in sctransport.js) fails with
// an error - This means that the signedAuthToken cannot be loaded by
// the auth engine and therefore, we need to unauthenticate the socket.
this._changeToUnauthenticatedStateAndClearTokens();
}

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "socketcluster-client",
"description": "SocketCluster JavaScript client",
"version": "6.5.0",
"version": "7.0.0",
"homepage": "http://socketcluster.io",
"contributors": [
{
Expand Down
60 changes: 30 additions & 30 deletions socketcluster.js
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ module.exports.destroy = function (options) {

module.exports.connections = SCSocketCreator.connections;

module.exports.version = '6.5.0';
module.exports.version = '7.0.0';

},{"./lib/scsocket":6,"./lib/scsocketcreator":7,"component-emitter":14}],4:[function(require,module,exports){
(function (global){
Expand Down Expand Up @@ -807,8 +807,6 @@ SCSocket.prototype.connect = SCSocket.prototype.open = function () {
this.state = this.CONNECTING;
Emitter.prototype.emit.call(this, 'connecting');

this._changeToUnauthenticatedState();

if (this.transport) {
this.transport.off();
}
Expand Down Expand Up @@ -868,18 +866,6 @@ SCSocket.prototype.destroy = function () {
this.disconnect();
};

SCSocket.prototype._changeToUnauthenticatedState = function () {
if (this.authState != this.UNAUTHENTICATED) {
var oldState = this.authState;
this.authState = this.UNAUTHENTICATED;
var stateChangeData = {
oldState: oldState,
newState: this.authState
};
Emitter.prototype.emit.call(this, 'authStateChange', stateChangeData);
}
};

SCSocket.prototype._changeToUnauthenticatedStateAndClearTokens = function () {
if (this.authState != this.UNAUTHENTICATED) {
var oldState = this.authState;
Expand Down Expand Up @@ -979,28 +965,41 @@ SCSocket.prototype.getSignedAuthToken = function () {
SCSocket.prototype.authenticate = function (signedAuthToken, callback) {
var self = this;

this._changeToUnauthenticatedState();

this.emit('#authenticate', signedAuthToken, function (err, authStatus) {
if (authStatus && authStatus.authError) {
authStatus.authError = scErrors.hydrateError(authStatus.authError);

if (authStatus && authStatus.isAuthenticated != null) {
// If authStatus is correctly formatted (has an isAuthenticated property),
// then we will rehydrate the authError.
if (authStatus.authError) {
authStatus.authError = scErrors.hydrateError(authStatus.authError);
}
} else {
// Some errors like BadConnectionError and TimeoutError will not pass a valid
// authStatus object to the current function, so we need to create it ourselves.
authStatus = {
isAuthenticated: self.authState,
authError: null
};
}
if (err) {
self._changeToUnauthenticatedStateAndClearTokens();
if (err.name != 'BadConnectionError' && err.name != 'TimeoutError') {
// In case of a bad/closed connection or a timeout, we maintain the last
// known auth state since those errors don't mean that the token is invalid.

self._changeToUnauthenticatedStateAndClearTokens();
}
callback && callback(err, authStatus);
} else {
self.auth.saveToken(self.authTokenName, signedAuthToken, {}, function (err) {
callback && callback(err, authStatus);
if (err) {
self._changeToUnauthenticatedStateAndClearTokens();
self._onSCError(err);
}
if (authStatus.isAuthenticated) {
self._changeToAuthenticatedState(signedAuthToken);
} else {
if (authStatus.isAuthenticated) {
self._changeToAuthenticatedState(signedAuthToken);
} else {
self._changeToUnauthenticatedStateAndClearTokens();
}
self._changeToUnauthenticatedStateAndClearTokens();
}
callback && callback(err, authStatus);
});
}
});
Expand Down Expand Up @@ -1049,6 +1048,9 @@ SCSocket.prototype._onSCOpen = function (status) {
this._changeToUnauthenticatedStateAndClearTokens();
}
} else {
// This can happen if auth.loadToken (in sctransport.js) fails with
// an error - This means that the signedAuthToken cannot be loaded by
// the auth engine and therefore, we need to unauthenticate the socket.
this._changeToUnauthenticatedStateAndClearTokens();
}

Expand Down Expand Up @@ -1134,8 +1136,8 @@ SCSocket.prototype._onSCClose = function (code, data, openAbort) {
this.pendingReconnectTimeout = null;
clearTimeout(this._reconnectTimeoutRef);

this._changeToUnauthenticatedState();
this._suspendSubscriptions();
this._abortAllPendingEventsDueToBadConnection(openAbort ? 'connectAbort' : 'disconnect');

// Try to reconnect
// on server ping timeout (4000)
Expand Down Expand Up @@ -1174,8 +1176,6 @@ SCSocket.prototype._onSCClose = function (code, data, openAbort) {
var err = new SocketProtocolError(SCSocket.errorStatuses[code] || failureMessage, code);
this._onSCError(err);
}

this._abortAllPendingEventsDueToBadConnection(openAbort ? 'connectAbort' : 'disconnect');
};

SCSocket.prototype._onSCEvent = function (event, data, res) {
Expand Down
8 changes: 4 additions & 4 deletions socketcluster.min.js

Large diffs are not rendered by default.

Loading

0 comments on commit 01a6677

Please sign in to comment.