-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat(realtime-chat): add Pusher library to the server * feat(realtime-chat): only for private groups * feat(realtime-chat): add authentication endpoint for Pusher * feat(realtime-chat): client proof of concept * fix typo in apidoc * feat(realtime-chat): redo authentication and write integration tests * remove firebase code * fix client side tests * fix line ending in bower.json * feat(realtime chat): use presence channels for parties, send events & disconnect clients if user leaves or is removed from party, automatically update UI * pusher: enable all events in the background * fix pusher integration tests
- Loading branch information
Showing
26 changed files
with
393 additions
and
285 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
102 changes: 102 additions & 0 deletions
102
test/api/v3/integration/user/auth/POST-user_auth_pusher.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
/* eslint-disable camelcase */ | ||
|
||
import { | ||
generateUser, | ||
requester, | ||
translate as t, | ||
} from '../../../../../helpers/api-integration/v3'; | ||
import { v4 as generateUUID } from 'uuid'; | ||
|
||
describe('POST /user/auth/pusher', () => { | ||
let user; | ||
let endpoint = '/user/auth/pusher'; | ||
|
||
beforeEach(async () => { | ||
user = await generateUser(); | ||
}); | ||
|
||
it('requires authentication', async () => { | ||
let api = requester(); | ||
|
||
await expect(api.post(endpoint)).to.eventually.be.rejected.and.eql({ | ||
code: 401, | ||
error: 'NotAuthorized', | ||
message: t('missingAuthHeaders'), | ||
}); | ||
}); | ||
|
||
it('returns an error if req.body.socket_id is missing', async () => { | ||
await expect(user.post(endpoint, { | ||
channel_name: '123', | ||
})).to.eventually.be.rejected.and.eql({ | ||
code: 400, | ||
error: 'BadRequest', | ||
message: t('invalidReqParams'), | ||
}); | ||
}); | ||
|
||
it('returns an error if req.body.channel_name is missing', async () => { | ||
await expect(user.post(endpoint, { | ||
socket_id: '123', | ||
})).to.eventually.be.rejected.and.eql({ | ||
code: 400, | ||
error: 'BadRequest', | ||
message: t('invalidReqParams'), | ||
}); | ||
}); | ||
|
||
it('returns an error if req.body.channel_name is badly formatted', async () => { | ||
await expect(user.post(endpoint, { | ||
channel_name: '123', | ||
socket_id: '123', | ||
})).to.eventually.be.rejected.and.eql({ | ||
code: 400, | ||
error: 'BadRequest', | ||
message: 'Invalid Pusher channel type.', | ||
}); | ||
}); | ||
|
||
it('returns an error if an invalid channel type is passed', async () => { | ||
await expect(user.post(endpoint, { | ||
channel_name: 'invalid-group-123', | ||
socket_id: '123', | ||
})).to.eventually.be.rejected.and.eql({ | ||
code: 400, | ||
error: 'BadRequest', | ||
message: 'Invalid Pusher channel type.', | ||
}); | ||
}); | ||
|
||
it('returns an error if an invalid resource type is passed', async () => { | ||
await expect(user.post(endpoint, { | ||
channel_name: 'presence-user-123', | ||
socket_id: '123', | ||
})).to.eventually.be.rejected.and.eql({ | ||
code: 400, | ||
error: 'BadRequest', | ||
message: 'Invalid Pusher resource type.', | ||
}); | ||
}); | ||
|
||
it('returns an error if an invalid resource id is passed', async () => { | ||
await expect(user.post(endpoint, { | ||
channel_name: 'presence-group-123', | ||
socket_id: '123', | ||
})).to.eventually.be.rejected.and.eql({ | ||
code: 400, | ||
error: 'BadRequest', | ||
message: 'Invalid Pusher resource id, must be a UUID.', | ||
}); | ||
}); | ||
|
||
it('returns an error if the passed resource id doesn\'t match the user\'s party', async () => { | ||
await expect(user.post(endpoint, { | ||
channel_name: `presence-group-${generateUUID()}`, | ||
socket_id: '123', | ||
})).to.eventually.be.rejected.and.eql({ | ||
code: 404, | ||
error: 'NotFound', | ||
message: 'Resource id must be the user\'s party.', | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
'use strict'; | ||
|
||
angular.module('habitrpg') | ||
.factory('Pusher', ['$rootScope', 'STORAGE_SETTINGS_ID', 'Groups', | ||
function($rootScope, STORAGE_SETTINGS_ID, Groups) { | ||
var settings = JSON.parse(localStorage.getItem(STORAGE_SETTINGS_ID)); | ||
var IS_PUSHER_ENABLED = window.env['PUSHER:ENABLED'] === 'true'; | ||
|
||
var api = { | ||
pusher: undefined, | ||
socketId: undefined, // when defined the user is connected | ||
}; | ||
|
||
// Setup chat channels once app is ready, only for parties for now | ||
var clearAppLoadedListener = $rootScope.$watch('appLoaded', function (after) { | ||
if (!after) return; | ||
clearAppLoadedListener(); // clean the event listerner | ||
|
||
if (!IS_PUSHER_ENABLED) return; | ||
|
||
var user = $rootScope.user; | ||
|
||
// Connect the user to Pusher and to the party's chat channel | ||
var partyId = user && $rootScope.user.party && $rootScope.user.party._id; | ||
if (!partyId) return; | ||
|
||
api.pusher = new Pusher(window.env['PUSHER:KEY'], { | ||
encrypted: true, | ||
authEndpoint: '/api/v3/user/auth/pusher', | ||
auth: { | ||
headers: { | ||
'x-api-user': settings && settings.auth && settings.auth.apiId, | ||
'x-api-key': settings && settings.auth && settings.auth.apiToken, | ||
}, | ||
}, | ||
}); | ||
|
||
api.pusher.connection.bind('error', function(err) { | ||
console.error(err); | ||
// TODO if( err.data.code === 4004 ) detected connection limit | ||
}); | ||
|
||
api.pusher.connection.bind('connected', function () { | ||
api.socketId = api.pusher.connection.socket_id; | ||
}); | ||
|
||
var partyChannelName = 'presence-group-' + partyId; | ||
var partyChannel = api.pusher.subscribe(partyChannelName); | ||
|
||
// When an error occurs while joining the channel | ||
partyChannel.bind('pusher:subscription_error', function(status) { | ||
console.error('Impossible to join the Pusher channel for your party, status: ', status); | ||
}); | ||
|
||
// When the user correctly enters the party channel | ||
partyChannel.bind('pusher:subscription_succeeded', function(members) { | ||
// TODO members = [{id, info}] | ||
}); | ||
|
||
// When a member enters the party channel | ||
partyChannel.bind('pusher:member_added', function(member) { | ||
// TODO member = {id, info} | ||
}); | ||
|
||
// When a member leaves the party channel | ||
partyChannel.bind('pusher:member_removed', function(member) { | ||
// TODO member = {id, info} | ||
}); | ||
|
||
// When the user is booted from the party, they get disconnected from Pusher | ||
partyChannel.bind('user-removed', function (data) { | ||
if (data.userId === user._id) { | ||
api.pusher.unsubscribe(partyChannelName); | ||
} | ||
}); | ||
|
||
// Same when the user leaves the party | ||
partyChannel.bind('user-left', function (data) { | ||
if (data.userId === user._id) { | ||
api.pusher.unsubscribe(partyChannelName); | ||
} | ||
}); | ||
|
||
// When a new chat message is posted | ||
partyChannel.bind('new-chat', function (data) { | ||
Groups.party().then(function () { | ||
// Groups.data.party.chat.unshift(data); | ||
// Groups.data.party.chat.splice(200); | ||
}); | ||
}); | ||
}); | ||
|
||
return api; | ||
}]); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.