Skip to content

Commit

Permalink
Use recently supported APIs for changes in user state, and track anon…
Browse files Browse the repository at this point in the history
…ymous connections.

- Idle monitor improved and more client-side tests added; fixes #27.
- Switched to Meteor connection APIs, closes #26.
- Anonymous connections tracked across login/logout; closes #22.
- Improved anonymous connection tracking should fix #2 and maybe fix #16 as well.
  • Loading branch information
mizzao committed Jun 26, 2014
1 parent 5c5657e commit 5477504
Show file tree
Hide file tree
Showing 13 changed files with 408 additions and 252 deletions.
4 changes: 3 additions & 1 deletion History.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
## vNEXT
## v0.5.0

* All connections are tracked, including anonymous (not authenticated) ones. Idle monitoring is supported on anonymous connections, and idle state will persist across a login/logout.
* The `Meteor.onConnection`, `connection.onClose`, and `Accounts.onLogin` functions are used to handle most changes in user state, except for logging out which is not directly supported in Meteor. This takes advantage of Meteor's new DDP heartbeats, and should improve issues with dangling connections caused by unclosed SockJS sockets.
* Ensure that the last activity timestamp is reset when restarting the idle monitor after stopping it.
* Add several unit tests for client-side idle monitoring logic.

Expand Down
2 changes: 1 addition & 1 deletion demo/.meteor/packages
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ accounts-testing
user-status
timesync
moment
bootboxjs
bootstrap-3
2 changes: 1 addition & 1 deletion demo/.meteor/release
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.8.1.3
0.8.2
26 changes: 5 additions & 21 deletions demo/demo.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ if Meteor.isClient
Template.status.isIdle = -> @isIdle() || "false"
Template.status.isMonitoring = -> @isMonitoring() || "false"

Template.serverStatus.anonymous = -> UserConnections.find(userId: $exists: false)
Template.serverStatus.users = -> Meteor.users.find()
Template.serverStatus.userClass = -> if @status?.idle then "warning" else "success"

Expand All @@ -54,40 +55,23 @@ if Meteor.isClient
Template.serverStatus.connections = -> UserConnections.find(userId: @_id)

Template.serverConnection.connectionClass = -> if @idle then "warning" else "success"
Template.serverConnection.loginTime = -> new Date(@loginTime).toLocaleString()
Template.serverConnection.loginTime = ->
return unless @loginTime?
new Date(@loginTime).toLocaleString()
Template.serverConnection.lastActivity = ->
lastActivity = @lastActivity
if lastActivity?
return relativeTime lastActivity
else
return "(active or not monitoring)"

Template.requestUsername.events =
Template.login.events =
"submit form": (e, tmpl) ->
e.preventDefault()
input = tmpl.find("input[name=username]")
input.blur()
Meteor.insecureUserLogin input.value, (err, res) -> console.log(err) if err

# Ask for a username as long as we're not logged in
usernameDialog = null

Meteor.startup ->
Deps.autorun ->
userId = Meteor.userId()
# Don't recompute this when status fields change
username = Meteor.users.findOne(userId, fields: {username: 1})?.username

if username and usernameDialog
usernameDialog.modal("hide")
usernameDialog = null
return

if !username and usernameDialog is null
usernameDialog = bootbox.dialog({ message: " " }).html('')
UI.insert UI.render(Template.requestUsername), usernameDialog[0]
return

# Start monitor as soon as we got a signal, captain!
Deps.autorun (c) ->
try # May be an error if time is not synced
Expand Down
35 changes: 14 additions & 21 deletions demo/demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,29 +33,19 @@ <h3>Instructions</h3>
{{#if loggedIn}}
<h3>You are logged in as:</h3>
{{> loginButtons}}
{{else}}
<form class="form-inline">
<p>Enter username to log in:</p>
{{! We use the pattern below because it matches \w in in autocomplete for user names}}
<input class="form-control" type="text" name="username" required
pattern="^[a-zA-Z][a-zA-Z0-9_]{5,12}$"
placeholder="Username..."
title="6-13 numbers or characters.">
<button type="submit" class="btn btn-primary">Login</button>
</form>
{{/if}}
</template>

<template name="requestUsername">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h3>Please enter a username to log in.</h3>
</div>
<div class="modal-body">
<form class="form-inline">
{{! We use the pattern below because it matches \w in in autocomplete for user names}}
<input class="form-control" type="text" name="username" required
pattern="^[a-zA-Z][a-zA-Z0-9_]{5,12}$"
placeholder="Username..."
title="6-13 numbers or characters.">
<button type="submit" class="btn btn-primary">Continue</button>
</form>
</div>
</div>
</div>
</template>

<template name="status">
<h3>Local status:</h3>

Expand Down Expand Up @@ -103,6 +93,9 @@ <h3>All user connections on server:</h3>
</tr>
</thead>
<tbody>
{{#each anonymous}}
{{> serverConnection}}
{{/each}}
{{#each users}}
<tr class="bold {{userClass}}">
<td colspan="2">{{username}}<br>(last login {{lastLogin}})</td>
Expand All @@ -119,7 +112,7 @@ <h3>All user connections on server:</h3>

<template name="serverConnection">
<tr class="{{connectionClass}}">
<td>{{_id}}<br>(login {{loginTime}})</td>
<td>{{_id}}{{#with loginTime}}<br>(login {{this}}){{/with}}</td>
<td>{{ipAddr}}</td>
<td>{{idle}}</td>
<td>{{lastActivity}}</td>
Expand Down
6 changes: 2 additions & 4 deletions demo/smart.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
{
"packages": {
"moment": {},
"bootboxjs": {},
"timesync": {
"path": "../../meteor-timesync"
},
"user-status": {
"path": ".."
},
"accounts-testing": {
"path": "../../../meteor-accounts-testing"
}
"accounts-testing": {},
"bootstrap-3": {}
}
}
15 changes: 5 additions & 10 deletions demo/smart.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,31 @@
"dependencies": {
"basePackages": {
"moment": {},
"bootboxjs": {},
"timesync": {
"path": "../../meteor-timesync"
},
"user-status": {
"path": ".."
},
"accounts-testing": {
"path": "../../../meteor-accounts-testing"
}
"accounts-testing": {},
"bootstrap-3": {}
},
"packages": {
"moment": {
"git": "https://github.com/acreeger/meteor-moment.git",
"tag": "v2.6.0",
"commit": "26156df681750fd6e6ed77043eef32b6653ebbdf"
},
"bootboxjs": {
"git": "https://github.com/TimHeckel/meteor-bootboxjs.git",
"tag": "v4.2.0",
"commit": "2b7d18ad028d9e7b37238ecf2a8a7970735cebd1"
},
"timesync": {
"path": "../../meteor-timesync"
},
"user-status": {
"path": ".."
},
"accounts-testing": {
"path": "../../../meteor-accounts-testing"
"git": "https://github.com/mizzao/meteor-accounts-testing.git",
"tag": "v0.1.0",
"commit": "9dc6839693aced99e11ad66f05851a3cac718d26"
},
"bootstrap-3": {
"git": "https://github.com/mangasocial/meteor-bootstrap-3.git",
Expand Down
5 changes: 2 additions & 3 deletions monitor.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ MonitorInternals = {
reportActive: (time) ->
Meteor.call "user-status-active", time

userId: -> Meteor.userId()
}

start = (settings) ->
Expand Down Expand Up @@ -158,8 +157,8 @@ Meteor.startup ->

# Report idle status whenever connection changes
Deps.autorun ->
# Don't report idle state unless we're logged and we're monitoring
return unless MonitorInternals.userId() and isMonitoring()
# Don't report idle state unless we're monitoring
return unless isMonitoring()

# XXX These will buffer across a disconnection - do we want that?
# The idle report will result in a duplicate message (with below)
Expand Down
2 changes: 1 addition & 1 deletion smart.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"description": "User connection and idle state tracking for Meteor",
"homepage": "https://github.com/mizzao/meteor-user-status",
"author": "Andrew Mao (http://www.andrewmao.net)",
"version": "0.4.1",
"version": "0.5.0",
"git": "https://github.com/mizzao/meteor-user-status.git",
"packages": {
"timesync": {}
Expand Down

0 comments on commit 5477504

Please sign in to comment.